WPF容器将所有子控件转为只读

  发布于 2023-02-13 10:28

我希望有一个WPF容器(面板,用户控件等)公开一个属性,以便将所有子项设置为只读(如果已设置).这应该就像将父控件设置为IsEnabled = false,这也会禁用所有子节点.应该考虑哪些孩子及其属性是固定的(例如TextBox.ReadOnly,DataGrid.ReadOnly,...).

我试图创建这样一个控件,它基本上迭代了可视树的所有子项(递归)并相应地处理控件.

这种方法很好,除了进一步更改会影响可视树的情况,以便添加新的子项.这对于ContentControl或ItemsControl都是如此.如果孩子们在浏览完它们后被添加到可视化树中,它们显然不是只读的.

我试图找到一个好的事件来做出反应(基本上在视觉树中检测新的孩子),但是找不到合适的东西.UpdateLayout被触发,但每次都经常通过可视树.

有办法解决这个问题吗?是否有另一种方法可以通过父元素上的绑定将所有(相关)子节点递归设置为只读?

(并且不会:我不希望将所有子项只读属性绑定到全局绑定.重点是将一个元素/部分传播给所有子节点)

1 个回答
  • 您可以使用提供值继承的附加属性来执行此操作:

    public class ReadOnlyPanel
    {
        public static readonly DependencyProperty IsReadOnlyProperty =
            DependencyProperty.RegisterAttached(
                "IsReadOnly", typeof(bool), typeof(ReadOnlyPanel),
                new FrameworkPropertyMetadata(false,
                    FrameworkPropertyMetadataOptions.Inherits, ReadOnlyPropertyChanged));
    
        public static bool GetIsReadOnly(DependencyObject o)
        {
            return (bool)o.GetValue(IsReadOnlyProperty);
        }
    
        public static void SetIsReadOnly(DependencyObject o, bool value)
        {
            o.SetValue(IsReadOnlyProperty, value);
        }
    
        private static void ReadOnlyPropertyChanged(
            DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            if (o is TextBox)
            {
                ((TextBox)o).IsReadOnly = (bool)e.NewValue;
            }
            // other types here
        }
    }
    

    您可以在XAML中使用它,如下所示:

    <StackPanel local:ReadOnlyPanel.IsReadOnly="{Binding IsChecked, ElementName=cb}">
        <CheckBox x:Name="cb" Content="ReadOnly"/>
        <TextBox Text="Hello"/>
    </StackPanel>
    

    2023-02-13 10:30 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有