MVVM DataGridTemplateColumn MVVM下的可见性绑定
我有一个DataGrid绑定到我的ViewModel中的ICollectionView。 DataGrid位于UserControl中,用于几种不同的数据场景,其中一些需要某些DataGrid列,而另一些则不需要。MVVM DataGridTemplateColumn MVVM下的可见性绑定
我只想将DataGridTemplateColumn的Visibility属性绑定到内部标签的Content属性,因此如果没有任何行包含值,它将被隐藏。我有一个String to Visibility转换器集,但无法弄清楚如何找到内部标签的Content属性。
<DataGridTemplateColumn Header="Groups" Width="*" CanUserSort="True" SortMemberPath="Groups" Visibility="{Binding ElementName=lbl, Path=Content, Converter={StaticResource StringToVisibilityConverter}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Name="lbl" Content="{Binding Path=Groups}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
有什么建议吗?
通过ViewModel上的Groups
属性可以更好地实现;因为这最终是Label
正在使用的。
<DataGridTemplateColumn Header="Groups" Width="*" CanUserSort="True" SortMemberPath="Groups" Visibility="{Binding Groups, Converter={StaticResource SomeConverter}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Name="lbl" Content="{Binding Path=Groups}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
是的,同样的。 – Will 2011-03-17 15:53:04
嗨,伙计们,我已经尝试过,并在运行时得到这个错误:System.Windows.Data错误:2:无法找到目标元素的治理FrameworkElement或FrameworkContentElement。 BindingExpression:路径=组;的DataItem = NULL;目标元素是'DataGridTemplateColumn'(HashCode = 38907373);目标属性是'可见性'(类型'可见性') – Aaron 2011-03-17 16:04:26
令人沮丧的是,当我使用在XAML中定义的CollectionViewSource时,通过将可见性绑定源设置为ColletionViewSource,这实际上起作用。我不得不将CollectionViewSource移动到ViewModel来处理排序/过滤,并且破坏了这个Visibility绑定。任何其他想法? – Aaron 2011-03-17 16:12:59
你不能这样做。绑定/名称解析不能以这种方式工作。为什么不,StringToVisibilityConverter
创建一个CollectionToVisibilityConverter
检查数据源(可能传入要检查的列/属性),查看该列/属性是否完全为空,然后将其转换为可见性?
我在Stack Overflow的某处(无法找到确切的帖子)DataGridColumn没有分配数据上下文,因为它们不是FrameworkElement。为了解决这个问题,我不得不使用代码类同此:
<DataGridTemplateColumn
Header="Groups"
Width="*"
CanUserSort="True"
SortMemberPath="Groups"
Visibility"{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(FrameworkElement.DataContext).IsGroupsVisible,
Converter={StaticResource booleanToVisiblityConverter}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Name="lbl" Content="{Binding Path=Groups}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Where
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="booleanToVisibilityConverter" />
</UserControl.Resources>
嗨安迪,有趣。现在没有得到任何绑定错误,但它仍然无法正常工作。转换器甚至没有被调用... – Aaron 2011-03-17 17:24:48
是在ViewGodel上DataGrid绑定的属性?或者它是DataGrid中的行绑定到的单个项目的属性?我认为它是两个,因为你想要显示单个单元格中的文本,并且网格中的列的可见性只能绑定到一个属性。 – 2011-03-17 17:36:20
它是一个ObservableCollection中的单个项目的属性,它被设置为CollectionViewSource的源,并作为ICollectionView返回到DataGrid。我也尝试将它绑定到ViewModel上的一个名为IsGroupsVisible的属性上,该属性不那么优雅,但它也没有选择它。 – Aaron 2011-03-17 17:39:10
要使用RelativeSource.Self
作为RelativeSource
的DataGridTemplateColumn
结合 - 你需要的DataGridContextHelper
添加到您的应用程序。对于WPF 4 DataGrid,这仍然是必需的。
<DataGridTemplateColumn
Header="Groups"
Width="*"
CanUserSort="True"
SortMemberPath="Groups"
Visibility"{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(FrameworkElement.DataContext).IsGroupsVisible,
Converter={StaticResource booleanToVisiblityConverter}}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Name="lbl" Content="{Binding Path=Groups}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
一百感谢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