0

我目前正在通过为 XAML 控件命名并在代码隐藏中设置 DataContext 将我的代码隐藏 (C#) 中的对象绑定到我的 XAML。

public partial class SmsControl: UserControl
{
    private readonly DataOrganizer _dataOrganizer;
    public FunctionalTester _funcTester;

    public SmsControl()
    {
        InitializeComponent();

        _dataOrganizer = new DataOrganizer();
        _funcTester = new FunctionalTester();

        // Set the datacontext appropriately
        grpModemInitialization.DataContext = _funcTester;
    }

    private async void Button_Click_2(object sender, RoutedEventArgs e)
    {
        await _funcTester.Test();
    }
}

还有我的 XAML...

 <!-- SMS Test Modem Initialization GroupBox -->
    <GroupBox x:Name="grpModemInitialization" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3"  Style="{StaticResource groupboxViewItem}">
        <GroupBox.Header>
            <Label Content="SMS Test Modem Initialization" Style="{StaticResource boldHeaderItem}"/>
        </GroupBox.Header>

        <!-- SMS Test Modem Initialization Grid -->
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="50"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Label Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Content="COM:" Style="{StaticResource boldHeaderItem}" />
            <ComboBox Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Style="{StaticResource comboBoxItem}" ItemsSource="{Binding AvailableCommPorts}" SelectedItem="{Binding SelectedCommPort}" />
            <Label Grid.Column="2" Grid.Row="0" Content="Modem Ready:" Style="{StaticResource boldHeaderItem}" />
            <Label Grid.Column="2" Grid.Row="1" Content="RSSI:" Style="{StaticResource boldHeaderItem}" />
            <Label Content="{Binding ModemReady}" Grid.Column="3" Grid.Row="0"  HorizontalContentAlignment="Left" VerticalAlignment="Center"/>
            <Label Content="{Binding ModemRssi}" Grid.Column="3" Grid.Row="1" HorizontalContentAlignment="Left" VerticalAlignment="Center" />
            <Label Grid.Column="4" Grid.Row="0" Content="Modem #:" Style="{StaticResource boldHeaderItem}"/>
            <Button Grid.Column="4" Grid.Row="1" Grid.ColumnSpan="2" Content="Initialize" />
            <Label Content="{Binding ModemNumber}" Grid.Column="5" Grid.Row="0" HorizontalContentAlignment="Left" VerticalAlignment="Center"/>
        </Grid>
    </GroupBox>

上面的代码工作正常 - 没有问题。我要问的是,是否有办法在 XAML 中设置 GroupBox 的 DataContext,引用我的 _funcTester 对象,而不是在代码隐藏中设置 DataContext?我问的原因是因为不同的控件需要绑定到代码隐藏中的不同对象,我没有找到关于如何做到这一点的好资源,除了我上面显示的(给每个“x:名称” XAML 控制并在代码隐藏中设置 DataContext)。任何帮助表示赞赏!谢谢!

4

2 回答 2

1

您不想在代码隐藏中按名称引用 UI 元素。实际上,任何时候您都可以避免命名对象,从而节省一点性能。通过设置您的应用程序以正确使用 MVVM,您可以获得性能、可读性、可维护性和代码分离。

您想进一步抽象事物以使用 MVVM 模式。您正在正确地进行绑定,但请考虑模式。你的观点都是正确的。考虑添加一个类,该类包含当前在代码隐藏中定义的属性以及在事件处理程序中调用的方法。

public class ViewModel : INotifyPropertyChanged
{
    private FunctionalTester _funcTester;
    public FunctionalTester FuncTester
    {
        get
        {
            return _funcTester;
        }
        set
        {
            _funcTester = value;
            OnPropertyChanged( "FuncTester" );
        }
    }

    public async void TestAsync( )
    {
        await _funcTester.Test( );
    }
}

绑定到 FuncTester 只是SomeProperty="{Binding FuncTester}"因为该对象被设置为您的视图的 DataContext。在这里可以找到一篇扩展这个想法的不错的文章。

为简洁起见,显然省略了一些内容(如INotifyPropertyChanged实现和您定义的其他属性)。但只需创建此类并将其分配为您的视图模型。然后 UI(Xaml 和代码隐藏)只真正处理 UI,而 ViewModel 真正处理数据和逻辑。大分离。对于您的事件处理程序,只需调用((ViewModel)this.DataContext).Test( );,您就可以即插即用您的 ViewModel 来动态更改功能。希望这可以帮助!

于 2013-09-25T13:05:25.947 回答
0

只需设置DataContext of whole UserControl to self即做

this.DataContext = this;在构造函数中。

然后为 _functinTester 定义属性

public FunctionalTester FuncTester { get {return _funcTester} };

现在在你的 xaml 中你可以做

<GroupBox x:Name="grpModemInitialization" DataContext="{Binding FuncTester}"/>

这样,由于您为整个用户控件设置了 DataContext,您可以将任何控件绑定到该 DataContext 中的任何属性

于 2013-09-25T12:54:03.213 回答