C#属性显示

news2025/9/17 19:04:31

功能:
显示对象的属性,包括可显示属性、可编辑属性、及不可编辑属性。
1、MainWindow.xaml

<Window x:Class="FlowChart.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FlowChart"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <DockPanel>
        <StackPanel DockPanel.Dock="Left" Width="300" Margin="0 0 10 0">
            <StackPanel Margin="0 10 0 10">
                <TextBlock Text="属性" FontWeight="Bold" Margin="0 0 0 10"/>
                <local:PropertiesView x:Name="_propertiesView" Height="200"/>
            </StackPanel>
        </StackPanel>
        <Border BorderBrush="Black" BorderThickness="1"></Border>
    </DockPanel>
</Window>

2、MainWindow.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FlowChart
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataInitialize();
        }

        public List<Selection> selections=new List<Selection>();
        public void DataInitialize()
        {
            Selection selection = new Selection();
            selection.Location=new Point(0,0);
            selection.Size=new Size(200,200);
            //selection.Name = "测试";
            _propertiesView.SelectedObject= selection;
        }
    }

    public class Selection:INotifyPropertyChanged
    {
        private Point _location;
        public Point Location
        {
            get { return _location; }
            set
            {
                _location = value;
                OnPropertyChanged("Location");
            }
        }

        private Size _size;
        //[Browsable(false)]
        public Size Size
        {
            get { return _size; }
            set
            {
                _size = value;
                OnPropertyChanged("Size");
            }
        }

        private string _name="Test";
        
        public string Name
        {
            get { return _name; }
            //set { _name = value;
            //    OnPropertyChanged("Name");
            //}
        }


        public override string ToString()
        {
            return GetType().Name;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

3、PropertiesView.xaml

<UserControl x:Class="FlowChart.PropertiesView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:FlowChart"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="300">
    <UserControl.Resources>
        <ControlTemplate x:Key="validationErrorTemplate">
            <DockPanel>
                <Image Source="Resources\empty.png" Height="16" Width="16" DockPanel.Dock="Right" Margin="-18 0 0 0"
                       ToolTip="{Binding ElementName=adorner,Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
                </Image>
                <AdornedElementPlaceholder x:Name="adorner"/>
            </DockPanel>
        </ControlTemplate>

        <Style x:Key="gridLineStyle" TargetType="Line">
            <Setter Property="Stroke" Value="Gray" />
            <Setter Property="Stretch" Value="Fill" />
            <Setter Property="Grid.ZIndex" Value="1000" />
        </Style>

        <Style x:Key="gridHorizontalLineStyle" TargetType="Line" BasedOn="{StaticResource gridLineStyle}">
            <Setter Property="X2" Value="1" />
            <Setter Property="VerticalAlignment" Value="Bottom" />
            <Setter Property="Grid.ColumnSpan"
                Value="{Binding 
                            Path=ColumnDefinitions.Count,
                            RelativeSource={RelativeSource AncestorType=Grid}}"/>
        </Style>

        <Style x:Key="gridVerticalLineStyle" TargetType="Line" BasedOn="{StaticResource gridLineStyle}">
            <Setter Property="Y2" Value="1" />
            <Setter Property="HorizontalAlignment" Value="Right" />
            <Setter Property="Grid.RowSpan" 
                Value="{Binding 
                            Path=RowDefinitions.Count,
                            RelativeSource={RelativeSource AncestorType=Grid}}"/>
        </Style>
    </UserControl.Resources>

    <Border BorderThickness="1" BorderBrush="Black">
        <DockPanel x:Name="_panel">
            <Border x:Name="_label" Width="50" Height="16">
                <TextBlock Text="Empty" TextAlignment="Center" Foreground="Gray"/>
            </Border>
            <ScrollViewer x:Name="_gridContainer" VerticalScrollBarVisibility="Auto">
                <Grid x:Name="_grid">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>

                    <Line Name="_vLine" Grid.Column="0" Grid.RowSpan="1000" Style="{StaticResource gridVerticalLineStyle}"/>
                    <GridSplitter Name="_splitter" Grid.RowSpan="1000"  Margin="0,0,-2,0" Width="4" 
                                  Background="White" Opacity="0.01" Grid.ZIndex="10000"/>

                </Grid>
            </ScrollViewer>
        </DockPanel>
    </Border>
</UserControl>

4、PropertiesView.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FlowChart
{
    /// <summary>
    /// PropertiesView.xaml 的交互逻辑
    /// </summary>
    public partial class PropertiesView : UserControl
    {
        public PropertiesView()
        {
            InitializeComponent();
            DisplayProperties();
        }

        private object _selectedObject;
        public object SelectedObject
        {
            get { return _selectedObject; }
            set
            {
                if (_selectedObject != value)
                {
                    var obj = _selectedObject as INotifyPropertyChanged;
                    if (obj != null)
                        obj.PropertyChanged -= PropertyChanged;

                    _selectedObject = value;
                    DisplayProperties();

                    obj = _selectedObject as INotifyPropertyChanged;
                    if (obj != null)
                        obj.PropertyChanged += PropertyChanged;
                }
            }
        }

        void PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            DisplayProperties();
        }

        private void DisplayProperties()
        {
            _panel.Children.Clear();
            ClearGrid();
            if (SelectedObject != null)
            {
                int row = 0;
                foreach (var prop in SelectedObject.GetType().GetProperties().OrderBy(p => p.Name))
                {
                    var attr = prop.GetCustomAttributes(typeof(BrowsableAttribute), true);
                    if (attr.Length == 0 || (attr[0] as BrowsableAttribute).Browsable)
                    {
                        DisplayProperty(prop, row);
                        row++;
                    }
                }
                _panel.Children.Add(_gridContainer);
            }
            else
            {
                _panel.Children.Add(_label);
            }
        }

        private void ClearGrid()
        {
            _grid.RowDefinitions.Clear();
            for (int i = _grid.Children.Count - 1; i >= 0; i--)
            {
                if (_grid.Children[i] != _vLine && _grid.Children[i] != _splitter)
                    _grid.Children.RemoveAt(i);
            }
        }

        private void DisplayProperty(PropertyInfo prop, int row)
        {
            var rowDef = new RowDefinition();
            rowDef.Height = new GridLength(Math.Max(20, this.FontSize * 2));
            _grid.RowDefinitions.Add(rowDef);

            var tb = new TextBlock() { Text = prop.Name };
            tb.Margin = new Thickness(4);
            Grid.SetColumn(tb, 0);
            Grid.SetRow(tb, _grid.RowDefinitions.Count - 1);

            var ed = new TextBox();
            ed.PreviewKeyDown += new KeyEventHandler(ed_KeyDown);
            ed.Margin = new Thickness(0, 2, 14, 0);
            ed.BorderThickness = new Thickness(0);
            Grid.SetColumn(ed, 1);
            Grid.SetRow(ed, _grid.RowDefinitions.Count - 1);

            var line = new Line();
            line.Style = (Style)Resources["gridHorizontalLineStyle"];
            Grid.SetRow(line, row);

            var binding = new Binding(prop.Name);
            binding.Source = SelectedObject;
            binding.ValidatesOnExceptions = true;
            binding.Mode = BindingMode.OneWay;
            ed.IsEnabled = false;
            if (prop.CanWrite)
            {
                ed.IsEnabled = true;
                var mi = prop.GetSetMethod();
                if (mi != null && mi.IsPublic)
                    binding.Mode = BindingMode.TwoWay;
            }
            ed.SetBinding(TextBox.TextProperty, binding);

            var template = (ControlTemplate)Resources["validationErrorTemplate"];
            Validation.SetErrorTemplate(ed, template);

            _grid.Children.Add(tb);
            _grid.Children.Add(ed);
            _grid.Children.Add(line);
        }

        void ed_KeyDown(object sender, KeyEventArgs e)
        {
            var ed = sender as TextBox;
            if (ed != null)
            {
                if (e.Key == Key.Enter)
                {
                    ed.GetBindingExpression(TextBox.TextProperty).UpdateSource();
                    e.Handled = true;
                }
                else if (e.Key == Key.Escape)
                    ed.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
            }
        }

    }
}

5、运行结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1555235.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用filezilla连接Ubuntu22.04虚拟机

获取电脑IP和虚拟机IP ① 在windows下ctrlR再输入cmd&#xff0c;打开指令窗口&#xff0c;输入 ipconfig 虚拟机连接电脑用的是NAT模式&#xff0c;故看VMnet8的IP地址 ② 查看虚拟机IP地址 终端输入 ifconfig 如果没安装&#xff0c;按提示安装net-tools sudo apt install …

vue3封装Element导航菜单

1. 导航外层布局 AsideView.vue <template><el-menu:default-active"defaultActive"class"my-menu":collapse"isCollapse":collapse-transition"false"open"handleOpen"close"handleClose"><menu…

云渲染实用工具:3ds max怎么改低版本?

3ds Max是建模领域广泛采用的专业软件&#xff0c;它通过定期更新来不断增强功能和提升性能。但这些频繁的更新有时会导致一些插件暂时无法与新版本完全兼容。为了解决这个问题&#xff0c;设计师们可以采用一个简单有效的方法&#xff0c;那就是将较新版本的3ds Max文件进行版…

拆分巨石:将MVPS和MVAS应用于遗留应用程序——可持续架构(六)

前言 MVP 和 MVA 的概念不仅适用于新应用程序&#xff1b;它们提供了一种新颖的方式来审视对遗留系统的范围变更&#xff0c;以防止过快地承担过多的变化 - 参见图1。MVA 可以帮助组织评估和更新其技术标准&#xff0c;通过展示新技术如何真正对支持 MVP 至关重要。创建 MVA 可…

uniapp对接极光推送(国内版以及海外版)

勾选push&#xff0c;但不要勾选unipush 国内版 网址&#xff1a;极光推送-快速集成消息推送功能,提升APP运营效率 (jiguang.cn) 进入后台&#xff0c;并选择对应应用开始配置 配置安卓包名 以及ios推送证书&#xff0c;是否将生产证书用于开发环境选择是 ios推送证书…

HarmonyOS ArkTS 骨架屏加载显示(二十五)

目录 前言1、骨架屏代码显示2、代码中引用3、效果图展示 前言 所谓骨架屏&#xff0c;就是在页面进行耗时加载时&#xff0c;先展示的等待 UI, 以告知用户程序目前正在运行&#xff0c;稍等即可。 等待的UI大部分是 loading 转圈的弹窗&#xff0c;有的是自己风格的小动画。其实…

【ERP原理与应用】作业·思考题三、四

思考题三 P77第四章3&#xff0c; 6&#xff0c;8 3.生产规划的基本内容是什么&#xff1f; 生产规划是根据企业未来一段时间内预计资源可用量和市场需求量之间的平衡所制定的概括性设想是根据企业所拥有的生产能力和需求预测&#xff0c;对企业未来较长一段时间内的产品、产…

elasticsearch _cat/indices docs.count is different than <index>/_count

今天遇到一个问题&#xff0c;kibana中看到文档数与下面语句查询到的不同 GET /_cat/count/jiankunking_xxxxx_product_expand_test?v GET /jiankunking_xxxxx_product_expand_test/_search?track_total_hitstrue语句查询结果 epoch timestamp count 1711433785 06:16…

用navicat进行mysql表结构同步

用navicat进行mysql表结构同步 前言新增一个列然后进行表结构同步删除一个列然后进行表结构同步把Int列转成TinyInt列&#xff0c;看数字溢出的情况下能不能表结构同步总结 前言 从同事那边了解到还能用navicat进行表结构同步&#xff0c;他会在发布更新的时候&#xff0c;直接…

MPDataDoc类介绍

MPDataDoc类介绍 使用mp数据库新接口mp_api.client.MPRester获取数据&#xff0c;例子如下&#xff1a; from mp_api.client import MPResterwith MPRester(API_KEY) as mpr:docs mpr.summary.search(material_ids["mp-1176451", "mp-561113"])以上代码返…

vue3+threejs新手从零开发卡牌游戏(二十一):添加战斗与生命值关联逻辑

首先将双方玩家的HP存入store中&#xff0c;stores/common.ts代码如下&#xff1a; import { ref, computed } from vue import { defineStore } from piniaexport const useCommonStore defineStore(common, () > {const _font ref() // 字体const p1HP ref(4000) // 己…

常见的Nginx+Redis+MQ+DB架构设计

三高&#xff0c;复杂的架构 SQRS CAP 缓存&#xff0c;限流 【Redis&#xff0c;缓存】 cache-aside 缓存cache&#xff1a;数据源的副本 store 1. Read/Write Through Pattern 读写穿透模式 redis&#xff1a;放当前在线用户&#xff0c;热点数据

iOS UIFont-真香警告之字体管理类

UIFont 系列传送门 第一弹加载本地字体:iOS UIFont-新增第三方字体 第二弹加载线上字体:iOS UIFont-实现三方字体的下载和使用 第三弹搭建字体管理类:iOS UIFont-真香警告之字体管理类 前言 不知道友们是否有过这种经历,项目已经迭代了很多版本,项目中的文件已经上千个了…

ARP协议定义及工作原理

ARP的定义 地址解析协议(Address Resolution Protocol&#xff0c;ARP)&#xff1a;ARP协议可以将IPv4地址(一种逻辑地址)转换为各种网络所需的硬件地址(一种物理地址)。换句话说&#xff0c;所谓的地址解析的目标就是发现逻辑地址与物理地址的映射关系。 ARP仅用于IPv4协议&a…

QT资源添加调用

添加资源文件&#xff0c;新建资源文件夹&#xff0c;命名resource&#xff0c;然后点下一步&#xff0c;点完成 资源&#xff0c;右键add Prefix 添加现有文件 展示的label图片切换 QLabel *led_show; #include "mainwindow.h" #include<QLabel> #include&l…

海豚【货运系统源码】货运小程序【用户端+司机端app】源码物流系统搬家系统源码师傅接单

技术栈&#xff1a;前端uniapp后端vuethinkphp 主要功能&#xff1a; 不通车型配置不通价格参数 多城市定位服务 支持发货地 途径地 目的地智能费用计算 支持日期时间 预约下单 支持添加跟单人数选择 支持下单优惠券抵扣 支持司机收藏订单评价 支持订单状态消息通知 支…

ps 常用命令

ps 常用命令 什么是ps&#xff1f; ps是process status的缩写&#xff0c;用于查看当前系统中运行的进程信息。它提供了关于进程的各种详细信息&#xff0c;如进程 PID、进程状态、CPU 使用情况、内存占用、运行时间等。 常用选项参数 -A &#xff1a;所有的进程均显示出来…

JZ-7-201XMT跳位合位监视专用继电器 220VDC 板后接线,面板安装 JOSEF约瑟

系列型号&#xff1a; JZ-7Y-201XMT跳位合位监视继电器&#xff1b; JZ-7J-201XMT跳位合位监视继电器&#xff1b; JZ-7Y-203XMT跳位合位监视继电器&#xff1b; JZ-7J-203XMT跳位合位监视继电器&#xff1b; JZ-7Y-204XMT跳位合位监视继电器&#xff1b; JZ-7J-204XMT跳…

【御控物联】JavaScript JSON结构转换(11):数组To数组——综合应用

文章目录 一、JSON结构转换是什么&#xff1f;二、术语解释三、案例之《JSON数组 To JSON数组》四、代码实现五、在线转换工具六、技术资料 一、JSON结构转换是什么&#xff1f; JSON结构转换指的是将一个JSON对象或JSON数组按照一定规则进行重组、筛选、映射或转换&#xff0…

Web漏洞-深入WAF注入绕过

目录 简要其他测试绕过 方式一:白名单&#xff08;实战中意义不大&#xff09; 方式二:静态资源 方式三: url白名单 方式四:爬虫白名单 #阿里云盾防SQL注入简要分析 #安全狗云盾SQL注入插件脚本编写 在攻防实战中&#xff0c;往往需要掌握一些特性&#xff0c;比如服务…