一百感謝SliverNinja和本文DataGridContextHelper。我的應用程序使用DataGrid和AutoGenerateColumns = False並使用DataGridTemplateColumn,因此在將列添加到網格之前設置了DataContext。
下面是附加屬性類:
public sealed class DataGridColumnDataContextForwardBehavior
{
private DataGrid dataGrid = null;
public DataGridColumnDataContextForwardBehavior(DataGrid dataGrid)
{
this.dataGrid = dataGrid;
dataGrid.Columns.CollectionChanged += DataGridColumns_CollectionChanged;
}
private void DataGridColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
var IsDataContextForwardingEnabled = GetIsDataContextForwardingEnabled(dataGrid);
if (IsDataContextForwardingEnabled && dataGrid.DataContext != null)
{
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in e.NewItems)
{
column.SetValue(FrameworkElement.DataContextProperty, dataGrid.DataContext);
}
}
}
}
static DataGridColumnDataContextForwardBehavior()
{
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(OnDataContextChanged)));
}
public static readonly DependencyProperty IsDataContextForwardingEnabledProperty =
DependencyProperty.RegisterAttached("IsDataContextForwardingEnabled", typeof(bool), typeof(DataGridColumnDataContextForwardBehavior),
new FrameworkPropertyMetadata(false, OnIsDataContextForwardingEnabledChanged));
public static void OnDataContextChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = obj as DataGrid;
if (dataGrid == null) return;
var IsDataContextForwardingEnabled = GetIsDataContextForwardingEnabled(dataGrid);
if (IsDataContextForwardingEnabled)
{
foreach (DataGridColumn col in dataGrid.Columns)
{
col.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
}
}
}
static void OnIsDataContextForwardingEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var dataGrid = obj as DataGrid;
if (dataGrid == null) return;
new DataGridColumnDataContextForwardBehavior(dataGrid);
if (!(e.NewValue is bool)) return;
if ((bool)e.NewValue && dataGrid.DataContext != null)
OnDataContextChanged(obj, new DependencyPropertyChangedEventArgs(FrameworkElement.DataContextProperty, dataGrid.DataContext, dataGrid.DataContext));
}
public static bool GetIsDataContextForwardingEnabled(DependencyObject dataGrid)
{
return (bool)dataGrid.GetValue(IsDataContextForwardingEnabledProperty);
}
public static void SetIsDataContextForwardingEnabled(DependencyObject dataGrid, bool value)
{
dataGrid.SetValue(IsDataContextForwardingEnabledProperty, value);
}
}
另一個非明顯的事情是正確的使用如何爲DataGridTemplateColumn結合:
<DataGrid bhv:DataGridColumnDataContextForwardBehavior.IsDataContextForwardingEnabled="True">
<DataGrid.Columns>
<DataGridTemplateColumn Visibility="{Binding Path=DataContext.Mode, RelativeSource={RelativeSource Self}, Converter={StaticResource SharedFilesModeToVisibilityConverter}, ConverterParameter={x:Static vmsf:SharedFilesMode.SharedOut}}"/>
它使用路徑是重要= DataContext.MyProp和RelativeSource Self
Only thing i不喜歡在當前實現 - 處理DataGrid.Columns.CollectionChanged事件我創建我的類的實例,不保留它的參考。因此理論上GC可能會在這段時間內殺死它,不確定如何在目前正確處理它,將會考慮並稍後更新我的帖子。任何想法和批評都是受歡迎的。
任何正在尋找答案的人,請參閱http:// stackoverflow。com/questions/7955318/bind-datagridtemplatecolumn-visibility – 2015-02-11 15:09:36