PropertyGrid自定义控件使用详解

2019-12-30 17:48:39于丽

PropertyGrid是一个很强大的控件,使用该控件做属性设置面板的一个好处就是你只需要专注于代码而无需关注UI的呈现,PropertyGrid会默认根据变量类型选择合适的控件显示。但是这也带来了一个问题,就是控件的使用变得不是特别灵活,主要表现在你无法根据你的需求很好的选择控件,比如当你需要用Slider控件来设置int型变量时,PropertyGrid默认的模板选择器是不支持的。网上找了许多资料基本都是介绍WinForm的实现方式,主要用到了IWindowFromService这个接口,并未找到合适的适合WPF的Demo,后来在参考了DEVExpress的官方Demo之后我做了一个基于WPF和DEV 16.2的PropertyGrid Demo,基本实现了上述功能。

为了实现这一点,需要自定义一个DataTemplateSeletor类,这也是本文的核心代码。

1.创建一个CustomPropertyGrid自定义控件:


<UserControl
  x:Class="PropertyGridDemo.PropertyGridControl.CustomPropertyGrid"
  xmlns="http://www.easck.com/winfx/2006/xaml/presentation"
  xmlns:x="http://www.easck.com/winfx/2006/xaml"
  xmlns:d="http://www.easck.com/expression/blend/2008"
  xmlns:dxprg="http://www.easck.com/winfx/2008/xaml/propertygrid"
  xmlns:local="clr-namespace:PropertyGridDemo.PropertyGridControl"
  xmlns:mc="http://www.easck.com/markup-compatibility/2006"
  d:DesignHeight="300"
  d:DesignWidth="300"
  mc:Ignorable="d">
  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <!-- 资源字典 -->
        <ResourceDictionary Source="../PropertyGridControl/DynamicallyAssignDataEditorsResources.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </UserControl.Resources>
  <Grid>
    <!-- PropertyDefinitionStyle:定义属性描述的风格模板 -->
    <!-- PropertyDefinitionTemplateSelector:定义一个模板选择器,对应一个继承自DataTemplateSelector的类 -->
    <!-- PropertyDefinitionsSource:定义一个获取数据属性集合的类,对应一个自定义类(本Demo中对应DataEditorsViewModel) -->
    <dxprg:PropertyGridControl
      x:Name="PropertyGridControl"
      Margin="24"
      DataContextChanged="PropertyGridControl_DataContextChanged"
      ExpandCategoriesWhenSelectedObjectChanged="True"
      PropertyDefinitionStyle="{StaticResource DynamicallyAssignDataEditorsPropertyDefinitionStyle}"
      PropertyDefinitionTemplateSelector="{StaticResource DynamicallyAssignDataEditorsTemplateSelector}"
      PropertyDefinitionsSource="{Binding Path=Properties, Source={StaticResource DemoDataProvider}}"
      ShowCategories="True"
      ShowDescriptionIn="Panel" />
  </Grid>
</UserControl>