如何在xaml中应用多个datacontext?

mad*_*mar 3 .net c# wpf xaml mvvm

我有多个视图模型。我对三个列表框使用了三个数据模板,这三个列表框与 3 个组合框及其所选项目绑定。但我的问题是,只有一个数据上下文可以完美工作。即,如果我写这样的代码

 public MainWindow()
        {           
            InitializeComponent();
            DataContext = new wbItemViewModel();
            DataContext = new IfItemViewModel();                         
        }
Run Code Online (Sandbox Code Playgroud)
 <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>
Run Code Online (Sandbox Code Playgroud)

只有最后一个 DataContext 是可见的。或者,如果我只编写一个 DataContext,则只有该 DataContext 出现在我的屏幕上。我在 stackoverflow 中尝试过不同的解决方案,但没有用。请帮忙。

Muk*_*iya 6

在 WPF 中,EveryUIElement始终只有一个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();
 }
Run Code Online (Sandbox Code Playgroud)

现在,您可以通过属性名称在 xaml 中使用所有其他子视图模型

  • @madhukumar,您需要更改 XAML 中的绑定,以便 Mukesh 的解决方案起作用。Ofc 如果您只是组合虚拟机而不更改 xaml,那么这是行不通的。 (3认同)