如何在自定义 wpf 控件上绑定数据网格列的可见性?
How can I bind visibility of a datagrid column on a custom wpf control?
我花了一上午时间查看相关帖子,NONE 我发现其中的帖子解决了我遇到的确切问题,尽管我在此过程中学到了更多东西。
(在 WPF 中将 MVVM 与用户控件结合使用)
场景:我需要创建一个可重复使用的控件,它是一个数据网格,根据表单要求显示两列或三列。我有一个已经创建的自定义控件,以及用于隐藏/显示此第三列选项的依赖项 属性:
*注意:此可见性完全取决于我将 属性 设置为什么,我从不需要根据其他区域的选择更改它。
public class MyCustomControl: Control
{
public static readonly DependencyProperty DisplayThirdColumnProperty = DependencyProperty.Register(
"DisplayThirdColumn",
typeof(bool),
typeof(MyCustomControl),
new FrameworkPropertyMetadata(false));
static MyCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
/// <summary>
/// Gets or sets a value indicating whether the the third column should display.
/// </summary>
public bool DisplayThirdColumn
{
get
{
return (bool)this.GetValue(DisplayThirdColumnProperty);
}
set
{
this.SetValue(DisplayThirdColumnProperty, value);
}
}
}
这里是 xaml.Generic:
<CheckBoxColumn Binding="{Binding StuffInThirdColumn}"
Header="ThirdColumn"
Visibility="{Binding DisplayThirdColumn,
Converter={StaticResource BooleanToVisibilityConverter},RelativeSource={RelativeSource TemplatedParent}}"/>
现在当我消耗控件时:
<MyControls:MyCustomControl DisplayThirdColumn="False"/>
如果我的 'newbieness' 出现了,我深表歉意,但我是否遗漏了一些明显的东西?当我将可见性 属性 设置为在控件 xaml.Generic 上显式折叠时,它正确地隐藏了列:
<CheckBoxColumn Visibility="Collapsed"..../>
输出window似乎表明它找不到要应用它的元素。
如果我不能使用相对来源,你知道我可以用另一种方法吗?
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=DisplayThirdColumn; DataItem=null; target element is 'CheckBoxColumn' (HashCode=19379515); target property is 'Visibility' (type 'Visibility')
可见性 属性 没有将 "False" 作为可能的值。如果你想隐藏你的控件,你要么需要写:
<CheckBoxColumn Visibility="Collapsed"/>
或
<CheckBoxColumn Visibility="Hidden"/>
如果你想在c#代码中设置可见性,写:
yourObject.Visibility = Visibility.Collapsed;
如果您需要有关可见性 属性 及其所有可能值的更多信息,请访问此处:https://msdn.microsoft.com/en-us/library/system.windows.visibility(v=vs.110).aspx
我会将可见性 属性 绑定到 ViewModel 中的布尔值,并使用 VisibilityConverter,请参阅 http://www.codeproject.com/Tips/285358/All-purpose-Boolean-to-Visibility-Converter。
这意味着如果我们绑定的布尔值 属性 是 true
,它将被转换为 Visibility.Visible
,如果为假,则 Visibility.Collapsed
.
感谢大家的评论和意见,感谢您抽出宝贵的时间(我总是很感激您抽出宝贵的时间!)
这是最终结果,万一其他人遇到这个问题,最终的结果是:
This post 帮了大忙,但我需要的语法缺少 TemplatedParent
:
的相对来源
(1) 我正在使用可消耗的控件,并希望能够在控件实现时设置此可见性。您可以使用上述 post 中的步骤访问 ViewModel 上下文。
(2) 您需要将绑定相对源放在代理或虚拟元素上的 TemplatedParent
(这是我缺少的部分)。
... In a ControlTemplate:
<FrameworkElement x:Name="dummyElementToGetDataContext"
DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Visibility="Collapsed" />
<DataGrid>
<DataGrid.Columns>
......
<CheckBoxColumn Binding="{Binding SecondColumnStuff}"
Visibility="{Binding DataContext.ShouldDisplaySecondColumn,
Converter={StaticResource BooleanToVisibilityConverter},
Source={x:Reference dummyElementToGetDataContext}}"
.............
或
创建代理并将其声明为资源时,将绑定相对源设置为模板化父级:
<DataGrid.Resources>
<controls:ControlProxy x:Key="ControlProxy" Control="{Binding RelativeSource={RelativeSource TemplatedParent}}"/>
</DataGrid.Resources>
我花了一上午时间查看相关帖子,NONE 我发现其中的帖子解决了我遇到的确切问题,尽管我在此过程中学到了更多东西。
(在 WPF 中将 MVVM 与用户控件结合使用)
场景:我需要创建一个可重复使用的控件,它是一个数据网格,根据表单要求显示两列或三列。我有一个已经创建的自定义控件,以及用于隐藏/显示此第三列选项的依赖项 属性:
*注意:此可见性完全取决于我将 属性 设置为什么,我从不需要根据其他区域的选择更改它。
public class MyCustomControl: Control
{
public static readonly DependencyProperty DisplayThirdColumnProperty = DependencyProperty.Register(
"DisplayThirdColumn",
typeof(bool),
typeof(MyCustomControl),
new FrameworkPropertyMetadata(false));
static MyCustomControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomControl), new FrameworkPropertyMetadata(typeof(MyCustomControl)));
}
/// <summary>
/// Gets or sets a value indicating whether the the third column should display.
/// </summary>
public bool DisplayThirdColumn
{
get
{
return (bool)this.GetValue(DisplayThirdColumnProperty);
}
set
{
this.SetValue(DisplayThirdColumnProperty, value);
}
}
}
这里是 xaml.Generic:
<CheckBoxColumn Binding="{Binding StuffInThirdColumn}"
Header="ThirdColumn"
Visibility="{Binding DisplayThirdColumn,
Converter={StaticResource BooleanToVisibilityConverter},RelativeSource={RelativeSource TemplatedParent}}"/>
现在当我消耗控件时:
<MyControls:MyCustomControl DisplayThirdColumn="False"/>
如果我的 'newbieness' 出现了,我深表歉意,但我是否遗漏了一些明显的东西?当我将可见性 属性 设置为在控件 xaml.Generic 上显式折叠时,它正确地隐藏了列:
<CheckBoxColumn Visibility="Collapsed"..../>
输出window似乎表明它找不到要应用它的元素。
如果我不能使用相对来源,你知道我可以用另一种方法吗?
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=DisplayThirdColumn; DataItem=null; target element is 'CheckBoxColumn' (HashCode=19379515); target property is 'Visibility' (type 'Visibility')
可见性 属性 没有将 "False" 作为可能的值。如果你想隐藏你的控件,你要么需要写:
<CheckBoxColumn Visibility="Collapsed"/>
或
<CheckBoxColumn Visibility="Hidden"/>
如果你想在c#代码中设置可见性,写:
yourObject.Visibility = Visibility.Collapsed;
如果您需要有关可见性 属性 及其所有可能值的更多信息,请访问此处:https://msdn.microsoft.com/en-us/library/system.windows.visibility(v=vs.110).aspx
我会将可见性 属性 绑定到 ViewModel 中的布尔值,并使用 VisibilityConverter,请参阅 http://www.codeproject.com/Tips/285358/All-purpose-Boolean-to-Visibility-Converter。
这意味着如果我们绑定的布尔值 属性 是 true
,它将被转换为 Visibility.Visible
,如果为假,则 Visibility.Collapsed
.
感谢大家的评论和意见,感谢您抽出宝贵的时间(我总是很感激您抽出宝贵的时间!)
这是最终结果,万一其他人遇到这个问题,最终的结果是:
This post 帮了大忙,但我需要的语法缺少 TemplatedParent
:
(1) 我正在使用可消耗的控件,并希望能够在控件实现时设置此可见性。您可以使用上述 post 中的步骤访问 ViewModel 上下文。
(2) 您需要将绑定相对源放在代理或虚拟元素上的 TemplatedParent
(这是我缺少的部分)。
... In a ControlTemplate:
<FrameworkElement x:Name="dummyElementToGetDataContext"
DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}"
Visibility="Collapsed" />
<DataGrid>
<DataGrid.Columns>
......
<CheckBoxColumn Binding="{Binding SecondColumnStuff}"
Visibility="{Binding DataContext.ShouldDisplaySecondColumn,
Converter={StaticResource BooleanToVisibilityConverter},
Source={x:Reference dummyElementToGetDataContext}}"
.............
或
创建代理并将其声明为资源时,将绑定相对源设置为模板化父级:
<DataGrid.Resources>
<controls:ControlProxy x:Key="ControlProxy" Control="{Binding RelativeSource={RelativeSource TemplatedParent}}"/>
</DataGrid.Resources>