我有一个DataGrid绑定到我的ViewModel中的ICollectionView。 DataGrid位于UserControl中,用于几种不同的数据场景,其中一些需要某些DataGrid列,而另一些则不需要。
我只想将DataGridTemplateColumn的Visibility属性绑定到内部标签的Content属性,因此如果没有任何行包含值,它将被隐藏。我有一个String to Visibility转换器集,但无法弄清楚如何找到内部lable的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>
有什么建议吗?
答案 0 :(得分:4)
我在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>
答案 1 :(得分:2)
要将RelativeSource.Self
用作RelativeSource
的{{1}}绑定,您需要将DataGridContextHelper
添加到您的应用中。这仍然是WPF 4 DataGrid所必需的。
DataGridTemplateColumn
答案 2 :(得分:1)
通过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>
答案 3 :(得分:0)
你不能这样做。绑定/名称解析不起作用。为什么不,而不是StringToVisibilityConverter
创建一个CollectionToVisibilityConverter
来检查数据源(可能传入列/属性进行检查),查看该列/属性是否完全为空,然后转换那是一个可见性?
答案 4 :(得分:0)
感谢 SliverNinja 和本文DataGridContextHelper。链接到源代码已经无法正常工作且无法下载,因此我编写了自己的附加Proeprty,使其适用于所有可能的情况(DataContext已更改,附加属性值已更改,已添加列)
我的应用程序将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}}"/>
使用 Path = DataContext.MyProp 和 RelativeSource Self
非常重要只有我不喜欢当前的实现 - 处理DataGrid.Columns.CollectionChanged事件我创建了我的类的实例,并且不保留它的引用。因此理论上GC可能会在一定时间内将其杀死,目前无法确定如何正确处理它,会考虑并稍后更新我的帖子。任何想法和批评都是受欢迎的。