1

私は、WPF や MVVM などを学習するのに役立つ小さなアプリケーションを持っています。ここにある Josh Smith の例を使用して、独自のアプリケーションを構築しています。sを追加するアプリケーションを取得しましたが、にバインドされてTabItemいる埋め込みにはデータが表示されません。下の画像を参照してください。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が の各行の情報を保持する場所DataGridResourceプロパティが設定されていることを確認できます。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ます。ユーザーがそれに入力すると、必要なテキストを含むセルがフィルター処理されて強調表示されますTextBoxDataGridただし、これは問題ではなく、このコードは機能します。これは、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>

これはうまくいきませんでした。これは、入力さDataGridれていない私のものResourceControlです。お時間を割いていただき、重ねてお礼申し上げます。

4

1 に答える 1

2

あなたはクラスではなくコントロールUserControl DockPanel.DataContextすることに縛られています。代わりに行う必要があるのは、. それを達成するには、最初にオブジェクトから削除してから、. また、アイテム バインディングを からに変更する必要があります。ResourceControlResourceDataViewModelDataContextResourceControlDataTemplateDataContext="{Binding ElementName=control}"ResourceControl.DockPanelResourceControl.DataContext<views:ResourceControl DataContext={Binding}"/>DataGridItemsSource="{Binding Path=(viewModels:Resources)}"ItemsSource="{Binding Path=Resources}"

元の質問の一部ではありませんが、同じテンプレートがタブ ヘッダーとタブ コンテンツに適用されます。これDataTemplateはタイプ固有であり、この場合、タブ ヘッダー コンテンツとタブ コンテンツは同じものであるためです。問題を解決するには、タイプを削除DataTemplateしてviewModels:ResourceDataViewModel、これを直接 main に入れますTabControl:

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