1

我有一个小应用程序来帮助自己学习 WPF 和 MVVM 等。我一直在使用 Josh Smith 在这里找到的示例来构建我自己的应用程序。我已经让应用程序添加了s,但是绑定到 anTabItem的嵌入没有显示任何数据,请参见下图:DataGridObservableCollection<ResourceViewModel>

例子

DataGrid是用蓝色包围的部分。由于UserControl某种原因,似乎也显示在选项卡本身中,但这不是我在这里询问的问题。UserControl包含 a ,其DataGrid绑定如下

<DataGrid ItemsSource="{Binding Resources}" 
          dataAccess:DataGridTextSearch.SearchValue="{Binding ElementName=searchBox, 
              Path=Text, UpdateSourceTrigger=PropertyChanged}" 
          AlternatingRowBackground="Gainsboro" 
          AlternationCount="2" 
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch">
...</DataGrid>

Resources属性在ViewModels命名空间中定义为

internal class ResourceDataViewModel : WorkspaceViewModel
{
    readonly ResourceDataRepository resourceRepository;
    public ObservableCollection<ResourceViewModel> Resources { get; private set; }
    ...
}

其中ResourceViewmodel保存 的每一行的信息DataGrid。我可以确认该Resource属性已填充。当我在 MVVM 之外使用相同的模型并Resource以相同的方式填充它时。有人可以告诉我为什么会发生这种情况吗?

我试图为绑定设置显式路径

ItemsSource="{Binding Path=(viewModels:Resources)}" 

但这也行不通。谢谢你的时间。


编辑。解决评论。我DataContextApp.xaml.cs文件中设置了

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    MainWindow window = new MainWindow();

    // Create the ViewModel to which 
    // the main window binds.
    MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();

    // When the ViewModel asks to be closed, 
    // close the window.
    EventHandler handler = null;
    handler = delegate
    {
        mainWindowViewModel.RequestClose -= handler;
        window.Close();
    };
    mainWindowViewModel.RequestClose += handler;

    // Allow all controls in the window to 
    // bind to the ViewModel by setting the 
    // DataContext, which propagates down 
    // the element tree.
    window.DataContext = mainWindowViewModel;
    window.Show();
}

的 XAML MainWindow

<Window x:Class="ResourceStudio.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModels="clr-namespace:ResourceStudio.ViewModels"
        xmlns:views="clr-namespace:ResourceStudio.Views"
        Title="MainWindow" Height="629.4" Width="814.4">
   <Window.Resources>
      <ResourceDictionary Source="MainWindowResources.xaml" />
   </Window.Resources>
   <Grid>
      <Grid.ColumnDefinitions>
         <ColumnDefinition Width="284*"/>
         <ColumnDefinition Width="567*"/>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
         <RowDefinition Height="48"/>
         <RowDefinition Height="*"/>
         <RowDefinition Height="24"/>
      </Grid.RowDefinitions>
      <DockPanel KeyboardNavigation.TabNavigation="None" 
                     Background="#FFBEC8D8" 
                 Grid.ColumnSpan="2" 
                 Margin="0,0,0.4,0">
         <Menu DockPanel.Dock="Top" 
                   Background="#FFF9F9F9" 
                   BorderBrush="Black" 
                   KeyboardNavigation.TabNavigation="Cycle">
            <MenuItem Header="_File">
               <MenuItem Header="Load _Resource..." 
                         Height="Auto" 
                         Command="{Binding LoadResourceCommand}"/>
               <MenuItem Header="_Add Language..." 
                         Height="Auto"/>
               <Separator/>
               <MenuItem Header="Close _Workspace" 
                         Height="Auto"
                         Command="{Binding CloseCommand}"/>
               <MenuItem Header="E_xit" 
                         Height="Auto" Command="{Binding CloseCommand}" />
            </MenuItem>
            <MenuItem Header="_Edit">
            </MenuItem>
         </Menu>
         <ToolBarTray DockPanel.Dock="Top" MaxHeight="24" Background="#FFF9F9F9">
            <ToolBar Background="#FFF9F9F9">
               <Button ToolBar.OverflowMode="Never">One</Button>
               <Button>Two</Button>
               <Button>Three</Button>
            </ToolBar>
         </ToolBarTray>
      </DockPanel>
      <Grid Grid.Row="1" Grid.ColumnSpan="2" Margin="0,0,0.4,23.6" Grid.RowSpan="2">
         <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
         </Grid.ColumnDefinitions>
         <TabControl ItemsSource="{Binding Path=Workspaces}" 
                     Grid.Column="2" 
                     HorizontalAlignment="Stretch" 
                     VerticalAlignment="Stretch" 
                     TabStripPlacement="Top" 
                     Height="Auto" 
                     Width="Auto">
         </TabControl>
      </Grid>
      <StatusBar Grid.Row="2" Grid.ColumnSpan="2" Margin="0,0.4,0.4,-0.4">
         <StatusBarItem DockPanel.Dock="Left" Background="#FF007ACC" Margin="0,2,0,0">
            <TextBlock Text="Ready" Margin="5,0,0,0"/>
         </StatusBarItem>
      </StatusBar>
   </Grid>
</Window>

在哪里MainWindowResources.xaml

<ResourceDictionary 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:viewModels="clr-namespace:ResourceStudio.ViewModels"
   xmlns:views="clr-namespace:ResourceStudio.Views"
   >
   <!--This template applies a ResourceControl view to an instance of the 
   ResourceDataViewModel class shown in the main window.-->
   <DataTemplate DataType="{x:Type viewModels:ResourceDataViewModel}">
      <views:ResourceControl/>
   </DataTemplate>

   <!--This template explains how to render the 'Workspace' 
   content area in the main window.-->
   <DataTemplate x:Key="WorkspacesTemplate">
      <TabControl 
      IsSynchronizedWithCurrentItem="True" 
      ItemsSource="{Binding}" 
      Margin="4"/>
   </DataTemplate>
</ResourceDictionary>

的完整代码ResourceControl.xaml是:

<UserControl x:Class="ResourceStudio.Views.ResourceControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:viewModels="clr-namespace:ResourceStudio.ViewModels" 
             xmlns:dataAccess="clr-namespace:ResourceStudio.DataAccess" 
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Name="control">
   <DockPanel DataContext="{Binding ElementName=control}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
      <TextBox Text="M"  DockPanel.Dock="Top" Name="searchBox" />
      <Grid DockPanel.Dock="Top">
         <Border BorderBrush="#FF007ACC" BorderThickness="2" HorizontalAlignment="Stretch" 
                 VerticalAlignment="Stretch">
            <DataGrid ItemsSource="{Binding Path=(viewModels:Resources)}" 
                      dataAccess:DataGridTextSearch.SearchValue="{Binding ElementName=searchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" 
                      AlternatingRowBackground="Gainsboro" AlternationCount="2" HorizontalAlignment="Stretch"
                      VerticalAlignment="Stretch">
               <DataGrid.Resources>
                  <dataAccess:SearchValueConverter x:Key="searchValueConverter"/>
                  <Style TargetType="{x:Type DataGridCell}">
                     <Setter Property="dataAccess:DataGridTextSearch.IsTextMatch">
                        <Setter.Value>
                           <MultiBinding Converter="{StaticResource searchValueConverter}">
                              <Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
                              <Binding RelativeSource="{RelativeSource Self}" Path="(dataAccess:DataGridTextSearch.SearchValue)" />
                           </MultiBinding>
                        </Setter.Value>
                     </Setter>
                     <Style.Triggers>
                        <Trigger Property="dataAccess:DataGridTextSearch.IsTextMatch" Value="True">
                           <Setter Property="Background" Value="Orange" />
                        </Trigger>
                     </Style.Triggers>
                  </Style>
               </DataGrid.Resources>
               <DataGrid.CellStyle>
                  <Style TargetType="DataGridCell" BasedOn="{StaticResource {x:Type DataGridCell}}">
                     <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                           <Setter Property="Background" Value="#FF007ACC"/>
                           <Setter Property="Foreground" Value="White"/>
                        </Trigger>
                     </Style.Triggers>
                  </Style>
               </DataGrid.CellStyle>
            </DataGrid>
         </Border>
      </Grid>
   </DockPanel>
</UserControl>

绑定TextBox到. DataGrid当用户输入TextBox过滤DataGrid器并突出显示包含所需文本的单元格时。然而,这不是问题,这段代码有效,它只是绑定到DataGrid我感兴趣的。再次感谢您的游览时间。

Edit2:根据@dkozl 的评论,我已经DataContext="{Binding ElementName=control}"DockPanel声明中删除了,所以我们现在有了

<DockPanel HorizontalAlignment="Stretch" 
           VerticalAlignment="Stretch">
...

MainWindowResource.xaml我现在有

<ResourceDictionary 
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
   xmlns:viewModels="clr-namespace:ResourceStudio.ViewModels"
   xmlns:views="clr-namespace:ResourceStudio.Views"
   >
   <!--This template applies a ResourceControl view to an instance of the 
   ResourceDataViewModel class shown in the main window.-->
   <DataTemplate DataType="{x:Type viewModels:ResourceDataViewModel}">
      <views:ResourceControl DataContext="{Binding}"/>
   </DataTemplate>

   <!--This template explains how to render the 'Workspace' 
   content area in the main window.-->
   <DataTemplate x:Key="WorkspacesTemplate">
      <TabControl 
      IsSynchronizedWithCurrentItem="True" 
      ItemsSource="{Binding}" 
      Margin="4"/>
   </DataTemplate>
</ResourceDictionary>

这没有奏效。那是我DataGridResourceControl里面没有被填充。再次感谢您的宝贵时间,非常感谢...

4

1 回答 1

2

Your UserControl DockPanel.DataContext is bound to ResourceControl control and not to ResourceDataViewModel class. What you need to do instead is to bind DataContext of ResourceControl in your DataTemplate. To achive that first remove DataContext="{Binding ElementName=control}" from ResourceControl.DockPanel and then bind ResourceControl.DataContext to your object by <views:ResourceControl DataContext={Binding}"/>. Also you need to change DataGrid items binding from ItemsSource="{Binding Path=(viewModels:Resources)}" to ItemsSource="{Binding Path=Resources}".

Not part of the original question but same template applies to tab header and tab content because DataTemplate is type specific and in this case tab header content and tab content is the same thing. To solve the issue remove DataTemplate for viewModels:ResourceDataViewModel type and put this directly into your main TabControl:

<TabControl.ContentTemplate>
   <DataTemplate>
      <views:ResourceControl DataContext={Binding}"/>
   </DataTemplat‌​e>
</TabControl.ContentTemplate>
于 2013-05-20T13:47:39.967 回答