前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF 给 Grid 的辅助方法 添加行列名称绑定

WPF 给 Grid 的辅助方法 添加行列名称绑定

作者头像
林德熙
发布2022-08-12 19:23:27
7150
发布2022-08-12 19:23:27
举报
文章被收录于专栏:林德熙的博客林德熙的博客

有一些设计师喜欢改改改,界面的整体布局总是变更,如给 Grid 加一列删一行等,每次这样的更改的时候,都需要小心修改 Grid 里面的元素设置的行列序号。我认为在 Grid 简单的时候,当然大多数时候都应该让 Grid 不那么复杂,那么序号的可读性不错。如果 Grid 行列数量比较多,那么此时行列的序号的可读性将会降低,本文来告诉大家一个简单的方法,可以给 Grid 的行列添加名称绑定,让元素绑定到行列可以不使用序号,而是使用名称

在开始之前让大家看一下效果,我有一个 Grid 的定义如下

代码语言:javascript
复制
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition local:GridExtensions.Name="R0" />
      <RowDefinition local:GridExtensions.Name="R1" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
      <ColumnDefinition />
      <ColumnDefinition />
      <ColumnDefinition local:GridExtensions.Name="C1" />
    </Grid.ColumnDefinitions>
  </Grid>

可以看到我在 Grid 上都附加了属性 GridExtensions.Name 属性,这就是本文的核心,通过附加属性实现让 Grid 的行列名称绑定。给 Grid 的行列一个命名,就可以让元素绑定命名而不是序号

代码语言:javascript
复制
    <TextBlock local:GridExtensions.RowName="R1" local:GridExtensions.ColumnName="C1" Text="12" />

添加一个 TextBlock 绑定行名为 R1 的行布局,绑定列是 C1 上,在 VisualStudio 设计器上可以看到效果如下

通过此方法就可以在给 Grid 加行列或删除行列的时候,减少修改一些元素的行列布局。因为元素绑定的是行列的名而不是序号,因此顺序修改的时候不会影响原有的界面代码

当前这个功能已合入到 HC 控件中,请通过 NuGet 安装 HandyControl

如不使用库,自己实现也简单,请看下面代码

代码语言:javascript
复制
    public class GridExtensions
    {
        public static readonly DependencyProperty NameProperty = DependencyProperty.RegisterAttached(
            "Name", typeof(string), typeof(GridExtensions), new PropertyMetadata(default(string)));

        public static void SetName(DependencyObject element, string value)
        {
            element.SetValue(NameProperty, value);
        }

        public static string GetName(DependencyObject element)
        {
            return (string) element.GetValue(NameProperty);
        }

        public static readonly DependencyProperty RowNameProperty = DependencyProperty.RegisterAttached(
            "RowName", typeof(string), typeof(GridExtensions),
            new PropertyMetadata(default(string), RowName_PropertyChanged));

        private static void RowName_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is FrameworkElement frameworkElement)
            {
                if (e.NewValue is string rowName)
                {
                    if (string.IsNullOrEmpty(rowName))
                    {
                        return;
                    }

                    if (frameworkElement.Parent is Grid grid)
                    {
                        for (var i = 0; i < grid.RowDefinitions.Count; i++)
                        {
                            var gridRowDefinition = grid.RowDefinitions[i];
                            var gridRowName = GetName(gridRowDefinition);
                            if (!string.IsNullOrEmpty(gridRowName) &&
                                gridRowName.Equals(rowName, StringComparison.Ordinal))
                            {
                                Grid.SetRow(frameworkElement, i);
                                return;
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("只有在Grid容器内才能设置 RowName 附加属性");
                    }
                }
            }
        }

        public static void SetRowName(DependencyObject element, string value)
        {
            element.SetValue(RowNameProperty, value);
        }

        public static string GetRowName(DependencyObject element)
        {
            return (string) element.GetValue(RowNameProperty);
        }

        public static readonly DependencyProperty ColumnNameProperty = DependencyProperty.RegisterAttached(
            "ColumnName", typeof(string), typeof(GridExtensions),
            new PropertyMetadata(default(string), ColumnName_PropertyChanged));

        private static void ColumnName_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is FrameworkElement frameworkElement)
            {
                if (e.NewValue is string columnName)
                {
                    if (string.IsNullOrEmpty(columnName))
                    {
                        return;
                    }

                    if (frameworkElement.Parent is Grid grid)
                    {
                        for (var i = 0; i < grid.ColumnDefinitions.Count; i++)
                        {
                            var gridColumnDefinition = grid.ColumnDefinitions[i];
                            var gridColumnName = GetName(gridColumnDefinition);
                            if (!string.IsNullOrEmpty(gridColumnName) &&
                                gridColumnName.Equals(columnName, StringComparison.Ordinal))
                            {
                                Grid.SetColumn(frameworkElement, i);
                                return;
                            }
                        }
                    }
                    else
                    {
                        throw new ArgumentException("只有在Grid容器内才能设置 ColumnName 附加属性");
                    }
                }
            }
        }

        public static void SetColumnName(DependencyObject element, string value)
        {
            element.SetValue(ColumnNameProperty, value);
        }

        public static string GetColumnName(DependencyObject element)
        {
            return (string) element.GetValue(ColumnNameProperty);
        }
    }

本文所有代码放在 githubgitee 欢迎小伙伴访问

更多请看 Alias for Grid‘s RowDefinition and ColumnDefinition · Issue #2844 · dotnet/wpf

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档