繁体   English   中英

在XAML中正确的代码隐藏对象数据绑定?

[英]Proper Code-Behind Object Data Binding in XAML?

我目前通过给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:Name”) XAML控件并在代码后面设置DataContext)。 任何帮助表示赞赏! 谢谢!

您不想在后面的代码中按名称引用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 SomeProperty="{Binding FuncTester}"因为该对象被设置为视图的DataContext。 在此可以找到有关此想法的扩展文章。

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

只需将DataContext of whole UserControl to selfDataContext of whole UserControl to self设置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中的任何属性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM