3

Commandデータを並べ替えるには、を使用する必要がありDataGridColumnHeaderます。DataGridに表示されるすべてのデータがないため、標準の並べ替え機能では不十分ですDataGrid。VMにすべてのデータが存在するわけではありません。(不可能です...多すぎます)サーバーにデータの具体的なページを要求するだけです。そして今、私はまた、ソートされたデータから具体的なページを取得したいと思います。

だから私はこれをしました:

 <DataGrid ItemsSource="{Binding Path=Entities, Mode=OneWay}" CanUserSortColumns="False" SelectionMode="Single" SelectedItem="{Binding Path=SelectedEntity}">
      <DataGrid.ColumnHeaderStyle>
           <Style TargetType="{x:Type DataGridColumnHeader}">
               <Setter Property="Command" Value="{Binding Path=MyCommand}"/>
               <Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
           </Style>
      </DataGrid.ColumnHeaderStyle>
      <DataGrid.Columns>
           <DataGridTemplateColumn >
                <DataGridTemplateColumn.Header>
                     <DataGridColumnHeader Content="Column1" />
                 </DataGridTemplateColumn.Header>
                 <DataGridTemplateColumn.CellTemplate>
                      <DataTemplate>
                          <TextBox Text="{Binding Path=Property1}"/>
                      </DataTemplate>
                 </DataGridTemplateColumn.CellTemplate>
           </DataGridTemplateColumn>
      </DataGrid.Columns>
 </DataGrid>

それは素晴らしい働きをします。AutoGenerateColumns="True"そして今、私は残念ながらそれがもう機能しないようにしたいだけです。自動生成された列で機能しない理由を説明し、解決策を提供してくれる人はいますか?前もって感謝します!

編集

それはおそらく、フォローも機能しないという事実と関係があります。

<DataGrid ItemsSource="{Binding Path=Entities, Mode=OneWay}" CanUserSortColumns="False" SelectionMode="Single" SelectedItem="{Binding Path=SelectedEntity}">
  <DataGrid.ColumnHeaderStyle>
       <Style TargetType="{x:Type DataGridColumnHeader}">
           <Setter Property="Command" Value="{Binding Path=MyCommand}"/>
           <Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
       </Style>
  </DataGrid.ColumnHeaderStyle>
  <DataGrid.Columns>
       <DataGridTemplateColumn>
            <!-- HERE IS THE CHANGE -->
            <DataGridTemplateColumn.Header>Column1</DataGridTemplateColumn.Header>
             <DataGridTemplateColumn.CellTemplate>
                  <DataTemplate>
                      <TextBox Text="{Binding Path=Property1}"/>
                  </DataTemplate>
             </DataGridTemplateColumn.CellTemplate>
       </DataGridTemplateColumn>
  </DataGrid.Columns>

しかし、スタイルが適用されます。私が試したので、私はこれを知っています:

<Style TargetType="{x:Type DataGridColumnHeader}">
   <Setter Property="Background" Value="Tomato"/> <!-- beautiful tomato background -->
   <Setter Property="Command" Value="{Binding Path=MyCommand}"/>
   <Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>
</Style>

列ヘッダーにはTomatoの背景がありますが、コマンドが機能しません。

EDIT2

以下が解決策です。コマンドバインディングを変更するとすべてが再び機能するため、どうやらDataGridColumnHeadersDataContextを継承していません。

<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},
                                Path=DataContext.MyCommand}"/>

しかし、それでも私はその理由をよく理解していません。したがって、詳細な説明で答えると、賞金が得られます。

4

2 に答える 2

2

DataGridColumnHeaderは、DataGridColumn.Headerのコンテナー項目です。たとえば、ListBoxItemは、 ListBoxItemsSource内の各項目のコンテナー項目です。

ListBoxItemのDataContextはListBoxのItemsSourceからのアイテムに設定されるため、DataGridColumnHeaderのDataContextがDataGridColumn.Headerオブジェクトに設定されるのは当然です。

于 2013-03-25T13:34:30.867 に答える
1

調査結果が示すように、自動生成された列には、DataContextが文字列ヘッダーオブジェクトに設定されたDataGridColumn.Headerがあります。

自動生成された列を使用せず、代わりにDataGridTemplateColumnとDataGridTemplateColumn.Headerを指定した場合でも、DataContextの標準の継承が適用されるため、初めて機能しました。

編集:クイック検索では、この動作が説明されている場所ですぐに結果が得られませんでした。ただし、事実を確認することはそれほど難しくありません。

ここに画像の説明を入力してください

Xaml:

<DataGrid ItemsSource="{Binding MyClasses}" AutoGenerateColumns="True" MouseRightButtonUp="DataGrid_MouseRightButtonUp_1" >
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.Header>
                <DataGridColumnHeader Content="Name (Manual Column)" />
            </DataGridTemplateColumn.Header>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=Name}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

ViewModel:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private ObservableCollection<Class1> _myClasses;
    public ObservableCollection<Class1> MyClasses { get { return _myClasses; } set { _myClasses = value; OnPropertyChanged("MyClasses"); } }

    public ViewModel()
    {
        MyClasses = new ObservableCollection<Class1>()
        {
            new Class1() { Name = "Andy" },
            new Class1() { Name = "Mark" },
            new Class1() { Name = "Peter" },
            new Class1() { Name = "Gregor" },
            new Class1() { Name = "Jenny" }
        };
    }
}

背後にあるコード(説明のみを目的としています):

private void DataGrid_MouseRightButtonUp_1(object sender, MouseButtonEventArgs e)
{
    if (e.OriginalSource is Microsoft.Windows.Themes.DataGridHeaderBorder)
    {
        object dataContext = ((Microsoft.Windows.Themes.DataGridHeaderBorder)e.OriginalSource).DataContext;
    }
}

手動の列ヘッダー(テキストブロックの外側)を右クリックすると、次のdataContextが生成されます。

ここに画像の説明を入力してください

自動生成された列ヘッダーを右クリックします。

ここに画像の説明を入力してください

于 2013-04-01T11:11:03.103 に答える