3

我需要使用CommandonDataGridColumnHeader对我的数据进行排序。标准DataGrid排序功能对我来说是不够的,因为DataGrid. 我的虚拟机中什至没有所有数据。(这是不可能的......它太多了)我只是从服务器请求具体的数据页面。现在我还想从排序数据中获取具体页面。

所以我这样做了:

 <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>

列标题有番茄背景,但命令不起作用。

编辑2

以下是解决方案。显然DataGridColumnHeaders不继承 DataContext,因为当我更改命令绑定时,一切都会再次运行。

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

但我仍然不太明白为什么。所以回答详细解释将获得赏金。

4

2 回答 2

2

DataGridColumnHeader是 DataGridColumn.Header 的容器项例如,ListBoxItemListBoxItemsSource中每个项的容器项。

由于 ListBoxItem 的 DataContext 将被设置为 ListBox 的 ItemsSource 中的一个项目,因此 DataGridColumnHeader 的 DataContext 将被设置为 DataGridColumn.Header 对象是很自然的。

于 2013-03-25T13:34:30.867 回答
1

正如您的发现所暗示的,自动生成的列将具有一个 DataGridColumn.Header,其 DataContext 设置为字符串标题对象。

如果您不使用自动生成的列,而是指定 DataGridTemplateColumn 和 DataGridTemplateColumn.Header,则 DataContext 的标准继承仍然适用,这就是它第一次为您工作的原因。

编辑:快速搜索没有提供描述此行为的即时结果。但是,验证事实并不难:

在此处输入图像描述

xml:

<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>

视图模型:

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;
    }
}

右键单击手动列标题(文本块外)会生成以下数据上下文:

在此处输入图像描述

右键单击自动生成的列标题:

在此处输入图像描述

于 2013-04-01T11:11:03.103 回答