我可以在DataGrid表中共享DataGrid.Columns

时间:2010-11-04 12:58:04

标签: wpf

我有3个数据网格共享相同的数据类型。我想配置一次列绑定,让3个datagrids共享资源。

e.g。

       <DataGrid Grid.Row="1" x:Name="primaryDG" ItemsSource="{Binding Path=dgSource AutoGenerateColumns="False">
       <DataGrid.Columns>
            <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/>
            <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/>
            <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/>
            <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/>
        </DataGrid.Columns>
    </DataGrid>

有没有办法为每个DataGrid设置ItemsSource,然后使用datatemplate或controltemplate来获取列?

3 个答案:

答案 0 :(得分:5)

是的......两种方式。你可以简单地为DataGrid添加一个样式来设置像这样的列......

<Style x:Key="MyColumnDefsStyle" x:Shared="True" TargetType="DataGrid">
    <Setter Property="Columns">
        <Setter.Value>
             <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/>
             <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/>
             <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/>
             <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/>
        </Setter.Value>
    </Setter>
</Style>

<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo1}" />
<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo2}" />
<DataGrid Style="{StaticResource MyColumnDefsStyle}" ItemsSource="{Binding Foo3}" />

如果您将它应用于自己可能已经使用样式的多个网格,那么它可以解决问题。

在这种情况下,另一种更灵活的方式更好。然而,这需要创建一个XAML友好的类来表示ObservableCollection<DataGridColumn>(虽然你在技术上只说了列,我喜欢完成自己,所以我也会为行做一个)然后将它们添加到一个你可以的地方XAML命名空间中的引用。 (我称我的xmlns:dge为'DataGridEnhancements')然后你就这样使用它:

在代码somwhere(我可以在应用程序范围内访问它)...

public class DataGridRowsCollection : ObservableCollection<DataGridRow>{}
public class DataGridColumnsCollection : ObservableCollection<DataGridColumn>{}

然后在资源......

<dge:DataGridColumnsCollection x:Key="MyColumnDefs" x:Shared="True">
    <DataGridTextColumn Width="Auto" Header="Column 1" Binding="{Binding Path=Col1}"/>
    <DataGridTextColumn Width="Auto" Header="Column 2" Binding="{Binding Path=Col2}"/>
    <DataGridTextColumn Width="Auto" Header="Column 3" Binding="{Binding Path=Col3}"/>
    <DataGridTextColumn Width="Auto" Header="Column 4" Binding="{Binding Path=Col4}"/>
</dge:DataGridColumnsCollection>

最后在XAML ......

<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo1}" />
<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo2}" />
<DataGrid Columns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo3}" />

HTH,

马克

修改 由于您无法设置DataGrid.Columns属性,因此您需要增强您的DataGridView(如评论中所述)。以下是EnhancedDataGrid的代码:

public class EnhancedDataGrid : DataGrid
    {
        //the dependency property for 'setting' our columns
        public static DependencyProperty SetColumnsProperty = DependencyProperty.Register(
            "SetColumns",
            typeof (ObservableCollection<DataGridColumn>),
            typeof (EnhancedDataGrid),
            new FrameworkPropertyMetadata
            {
                DefaultValue = new ObservableCollection<DataGridColumn>(),
                PropertyChangedCallback = EnhancedDataGrid.SetColumnsChanged,
                AffectsRender = true,
                AffectsMeasure = true,
                AffectsParentMeasure = true,
                IsAnimationProhibited = true,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            });

        //callback to reset the columns when our dependency property changes
        private static void SetColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var datagrid = (DataGrid) d;

            datagrid.Columns.Clear();
            foreach (var column in (ObservableCollection<DataGridColumn>)e.NewValue)
            {
                datagrid.Columns.Add(column);
            }
        }

        //The dependency property wrapper (so that you can consume it inside your xaml)
        public ObservableCollection<DataGridColumn> SetColumns
        {
            get { return (ObservableCollection<DataGridColumn>) this.GetValue(EnhancedDataGrid.SetColumnsProperty); }
            set { this.SetValue(EnhancedDataGrid.SetColumnsProperty, value); }
        } 
    }

现在,您可以使用CustomControl中创建的SetColumns依赖项属性设置列:

<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo1}" />
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo2}" />
<custom:EnhancedDataGrid SetColumns="{StaticResource MyColumnDefs}" ItemsSource="{Binding Foo3}" />

答案 1 :(得分:1)

您可以创建自定义控件,以包装数据网格并将数据传递给它。控件将在网格上设置数据。

答案 2 :(得分:1)

这个答案基于MarquelV的解决方案。在他的回答中(以及在评论中),他提到了一个名为sendmail_path="C:\xampp\mailtodisk\mailtodisk.exe" 的自定义控件,在那里他为设置 EnhancedDataGrid属性提供了逻辑。以下是DataGrid.Columns的代码:

EnhancedDataGrid

现在,您可以使用CustomControl中创建的SetColumns依赖项属性设置列:

public class EnhancedDataGrid : DataGrid
    {
        //the dependency property for 'setting' our columns
        public static DependencyProperty SetColumnsProperty = DependencyProperty.Register(
            "SetColumns",
            typeof (ObservableCollection<DataGridColumn>),
            typeof (EnhancedDataGrid),
            new FrameworkPropertyMetadata
            {
                DefaultValue = new ObservableCollection<DataGridColumn>(),
                PropertyChangedCallback = EnhancedDataGrid.SetColumnsChanged,
                AffectsRender = true,
                AffectsMeasure = true,
                AffectsParentMeasure = true,
                IsAnimationProhibited = true,
                DefaultUpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
            });

        //callback to reset the columns when our dependency property changes
        private static void SetColumnsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var datagrid = (DataGrid) d;

            datagrid.Columns.Clear();
            foreach (var column in (ObservableCollection<DataGridColumn>)e.NewValue)
            {
                datagrid.Columns.Add(column);
            }
        }

        //The dependency property wrapper (so that you can consume it inside your xaml)
        public ObservableCollection<DataGridColumn> SetColumns
        {
            get { return (ObservableCollection<DataGridColumn>) this.GetValue(EnhancedDataGrid.SetColumnsProperty); }
            set { this.SetValue(EnhancedDataGrid.SetColumnsProperty, value); }
        } 
    }