如何在自定义 wpf 控件上绑定数据网格列的可见性?

Posted

技术标签:

【中文标题】如何在自定义 wpf 控件上绑定数据网格列的可见性?【英文标题】:How can I bind visibility of a datagrid column on a custom wpf control? 【发布时间】:2015-08-23 08:05:55 【问题描述】:

我花了一上午的时间查看相关帖子,但我发现没有一篇能解决我遇到的确切问题,尽管我在此过程中学到了更多东西。

(在 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"/>

如果我的“新手”出现,我深表歉意,但我在这里遗漏了一些明显的东西吗?当我在控件 xaml.Generic 上将 Visiblity 属性显式设置为折叠时,它正确地隐藏了该列:

<CheckBoxColumn Visibility="Collapsed"..../>

输出窗口似乎表明它找不到要应用它的元素。

如果我不能使用相对来源,你知道我可以用另一种方法吗?

System.Windows.Data 错误:2:找不到目标元素的管理 FrameworkElement 或 FrameworkContentElement。绑定表达式:路径=DisplayThirdColumn;数据项=空;目标元素是“CheckBoxColumn”(HashCode=19379515);目标属性是“可见性”(类型“可见性”)

【问题讨论】:

列不在同一个可视化树中,因此不能继承DataContext。您可以在这里寻找解决方案:***.com/questions/22073740/… 【参考方案1】:

Visibility 属性不会将“False”作为可能的值。如果要隐藏控件,则需要编写:

<CheckBoxColumn Visibility="Collapsed"/>

<CheckBoxColumn Visibility="Hidden"/>

如果你想在c#代码中设置Visibility,写:

yourObject.Visibility = Visibility.Collapsed;

如果您需要有关可见性属性及其所有可能值的更多信息,请访问此处:https://msdn.microsoft.com/en-us/library/system.windows.visibility(v=vs.110).aspx

【讨论】:

更新了原帖以删除Visibility="False"的错字【参考方案2】:

我会将可见性属性绑定到 ViewModel 中的布尔值,并使用 VisibilityConverter,请参阅 http://www.codeproject.com/Tips/285358/All-purpose-Boolean-to-Visibility-Converter。

这意味着如果我们绑定的布尔属性是true,它将被转换为Visibility.Visible,如果为false,则Visibility.Collapsed

【讨论】:

【参考方案3】:

感谢大家的 cmets 和投入,感谢您抽出一分钟(我总是感谢您抽出宝贵的时间!)

这是最终结果,如果其他人遇到这种情况,最终会起作用:

This post 帮了大忙,但我需要的语法缺少TemplatedParent 的相对来源:

(1) 我正在使用消耗性控件,并且希望能够在实现控件时设置此可见性。您可以使用上述帖子中的步骤进入 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>

【讨论】:

您还应该将您的答案标记为已接受的答案,以防其他人遇到您的问题。

以上是关于如何在自定义 wpf 控件上绑定数据网格列的可见性?的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义列的 WPF 数据网格绑定

如何将 WPF DataGrid DataColumns 可见性绑定到 UserControl 的 ViewModel 上的属性?

WPF - 将 UserControl 可见性绑定到属性

我可以将 WPF ComboBox 控件的可见性绑定到从命令获得的项目的存在/不存在吗? [关闭]

WPF 绑定不更新可见性

如何基于二维数组填充 WPF 网格