2011-11-10 148 views
1

可能重复:
Wpf Toolkit. Bind DataGrid Column Header to DynamicResource
WPF Error: Cannot find govering FrameworkElement for target element绑定DataGrid列标题

我使用MVVM模式,所以对我的看法,我试图将列绑定创建WPF应用程序将DataGrid列的标题添加到我的视图模型上的属性,该属性是DataGrid所在视图的数据上下文。

XAML:

<DataGrid Name="DailyData" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding Path=DailyDataViewModels}" HorizontalAlignment="Stretch"> 
        <DataGrid.Columns> 
         <DataGridTextColumn Header="{Binding InflowVolumeLabel}" Binding="{Binding InflowVolume}"></DataGridTextColumn> 
        </DataGrid.Columns> 
       </DataGrid> 

但是头只显示了空白,似乎并不试图绑定到指定的属性,你怎么可以绑定一个DataGrid列标题?

+1

@parapurarajkumar:本'BindingMarkupExtension'认为任何无锁值是'Path',所以是的,它是故意的,但它也是正确。 – user7116

回答

1

你已经遇到了一个整洁的问题与DataGrid.Columns集合,即他们不是同一视觉树的成员,因此只有Binding属性似乎工作。

我发现唯一可行的方法是将一个附加属性添加到DataGrid,它将在数据加载后应用标头。

public static readonly DependencyProperty ColumnHeadersProperty = 
    DependencyProperty.RegisterAttached(
     "ColumnHeaders", 
     typeof(IDictionary<string, string>), 
     typeof(DataGrid), 
     new UIPropertyMetadata(
      new Dictionary<string,string>(), 
      ColumnHeadersPropertyChanged)); 

public static IDictionary<string,string> GetColumnHeaders(DependencyObject obj) 
{ 
    return (IDictionary<string, string>)obj.GetValue(ColumnHeadersProperty); 
} 

public static void SetColumnHeaders(DependencyObject obj, 
    IDictionary<string, string> value) 
{ 
    obj.SetValue(ColumnHeadersProperty, value); 
} 

static void ColumnHeadersPropertyChanged(DependencyObject sender, 
    DependencyPropertyChangedEventArgs e) 
{ 
    var dataGrid = sender as DataGrid; 
    if (dataGrid != null && e.NewValue != null) 
    { 
     dataGrid.AutoGeneratingColumn += AddColumnHeaders; 
    } 
} 

static void AddColumnHeaders(object sender, 
    DataGridAutoGeneratingColumnEventArgs e) 
{ 
    var headers = GetColumnHeaders(sender as DataGrid); 
    if (headers.ContainsKey(e.PropertyName)) 
    { 
     e.Column.Header = headers[e.PropertyName]; 
    } 
} 

可能使用的一样(可以改善):

// you could change it to use Column.DisplayIndex 
this.dataGrid.SetValue(
    DataGridEx.ColumnHeadersProperty, 
    new Dictionary<string, string> 
    { 
     { "PropertyName1", "Header 1" }, 
     { "PropertyName2", "Header 2" }, 
     { "PropertyName3", "Header 3" }, 
    });