如何在XAML中应用多个DataContext?

3

我是一名有用的助手,可以为您提供文本翻译。

我有多个视图模型。我使用了三个数据模板来为三个列表框提供绑定,这些列表框与3个组合框及其选定项相关联。但我的问题是,只有一个数据上下文能够完美地工作。也就是说, 如果我写的代码如下:

 public MainWindow()
        {           
            InitializeComponent();
            DataContext = new wbItemViewModel();
            DataContext = new IfItemViewModel();                         
        }

 <Window.Resources>     

     <DataTemplate x:Key="wbObjectsDataTemplate">
        <Grid>               

            <ItemsControl Grid.ColumnSpan="4" Grid.RowSpan="4" Height="24" Width="642" >
                <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Width="697"  Margin="10,0,0,0" Height="54" >  
                    <Label Content="{Binding WBName_lbl}" Margin="0,3,0,5" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"/>               

                    <ComboBox x:Name="wbselect"  Margin="5,0,10,1" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0">
                        <ComboBoxItem x:Name="wbstraight" IsSelected="True" Content="straight"></ComboBoxItem>
                        <ComboBoxItem x:Name="wbtapered" Content="tapered"></ComboBoxItem>
                    </ComboBox>


                    <TextBox x:Name="wbDesc" Margin="18,0,20,1" Grid.Column="2" Grid.Row="0">
                    </TextBox>

                    <Label x:Name="wblengthvalue" Margin="247,0,54,5" FontSize="8" Grid.Row="1" Grid.Column="2"/>



                </Grid>
            </ItemsControl>
            <!--</GroupBox>-->
        </Grid>
    </DataTemplate>

    <DataTemplate x:Key="ifObjectsDataTemplate">
        <Grid>               
            <ItemsControl Grid.ColumnSpan="4" Grid.RowSpan="4" Height="24" Width="642" >
                <Grid HorizontalAlignment="Left" VerticalAlignment="Top" Width="697"  Margin="10,0,0,0" Height="54" >                      

                    </Grid.RowDefinitions>

                    <Label Content="{Binding IFName_lbl}" Margin="0,3,0,5" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"/>                       

                    <ComboBox x:Name="ifselect"  Margin="5,0,10,1" Grid.Column="1" Grid.ColumnSpan="1" Grid.Row="0">
                        <ComboBoxItem x:Name="ifstraight" IsSelected="True" Content="straight"></ComboBoxItem>
                        <ComboBoxItem x:Name="iftapered" Content="tapered"></ComboBoxItem>
                    </ComboBox>

                    <TextBox x:Name="ifDesc" Margin="18,0,20,1" Grid.Column="2" Grid.Row="0">
                    </TextBox>

                    <Label x:Name="iflengthvalue" Margin="247,0,54,5" FontSize="8" Grid.Row="1" Grid.Column="2"/>



                </Grid>
            </ItemsControl>                
        </Grid>
    </DataTemplate>

    </Window.Resources>
     <ComboBox x:Name="wbCombo" ItemsSource="{Binding wbComboBoxList}" SelectedItem="{Binding wbSelectedComboIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"  Height="20" Width="92" SelectedIndex="4" Canvas.Left="102" Canvas.Top="19"/>                       
                            <ComboBox x:Name="ifCombo" ItemsSource="{Binding ifComboBoxList}"  SelectedItem="{Binding ifSelectedComboIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="20" Width="92" SelectedIndex="4"
     Canvas.Left="302" Canvas.Top="19" />
     <ListBox x:Name="wbListDataTemplate" ItemsSource="{Binding wbVisibleItems}"           
          ItemTemplate="{DynamicResource wbObjectsDataTemplate}"
           Background="{x:Null}" 
SelectedItem="{Binding wbSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsSynchronizedWithCurrentItem="True" Canvas.Top="51" Height="153" Width="655">
                            </ListBox>
    <ListBox x:Name="ifListDataTemplate"  ItemsSource="{Binding ifVisibleItems}"             
    ItemTemplate="{DynamicResource ifObjectsDataTemplate}"
                                      Background="{x:Null}"
                                     SelectedItem="{Binding ifSelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                     IsSynchronizedWithCurrentItem="True" Canvas.Top="203" Height="153" Width="655">
                            </ListBox>
</Window>

只有最后一个DataContext是可见的。如果我只写一个单独的DataContext,那么只有它会出现在我的屏幕上。我已经尝试了stackoverflow上的不同解决方案,但没有用。请帮忙。
1个回答

6
在WPF中,每个UIElement始终只有一个DataContext属性。因此,如果您多次分配此属性,则会覆盖旧值。
解决您的问题的方法是使用一个组合视图模型类,其中包含所有三个子视图模型。然后,您可以为每个UI元素分配此属性。
示例:
public class CombinedViewModel
{
    public wbItemViewModel WebItemVM= new wbItemViewModel();
    public InnerFlangeViewModel InnerFlangVM= new InnerFlangeViewModel();
    public OuterFlangeViewModel OuterVM= new OuterFlangeViewModel();       
}

 public MainWindow()
 {           
    InitializeComponent();
    DataContext = new CombinedViewModel();
 }

现在你可以通过属性名在你的XAML中使用所有其他的子视图模型。

这有什么问题,你能具体说明吗? - Mukesh Methaniya
你能把绑定表达式放在这里吗?你是如何进行绑定的? - Mukesh Methaniya
3
你需要更改XAML中的绑定,这样才能使Mukesh的解决方案起作用。如果你只是简单地合并视图模型而没有更改XAML,那么这个解决方案将无法起作用。 - Shakra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接