簡體   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