如何在PropertyGrid中自定義控件

本篇文章為大家展示了如何在PropertyGrid中自定義控件,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站建設(shè)、成都網(wǎng)站制作與策劃設(shè)計(jì),金堂縣網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:金堂縣等地區(qū)。金堂縣做網(wǎng)站價(jià)格咨詢:18982081108

1.創(chuàng)建一個(gè)CustomPropertyGrid自定義控件:

<UserControl
  x:Class="PropertyGridDemo.PropertyGridControl.CustomPropertyGrid"
  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:dxprg="http://schemas.devexpress.com/winfx/2008/xaml/propertygrid"
  xmlns:local="clr-namespace:PropertyGridDemo.PropertyGridControl"
  xmlns:mc="http://schemas.openxmlformats.org/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:定義屬性描述的風(fēng)格模板 -->
    <!-- PropertyDefinitionTemplateSelector:定義一個(gè)模板選擇器,對(duì)應(yīng)一個(gè)繼承自DataTemplateSelector的類 -->
    <!-- PropertyDefinitionsSource:定義一個(gè)獲取數(shù)據(jù)屬性集合的類,對(duì)應(yīng)一個(gè)自定義類(本Demo中對(duì)應(yīng)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>

該控件使用的資源字典如下:

<ResourceDictionary
  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:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
  xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
  xmlns:dxprg="http://schemas.devexpress.com/winfx/2008/xaml/propertygrid"
  xmlns:local="clr-namespace:PropertyGridDemo.PropertyGridControl"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  mc:Ignorable="d">

  <local:DynamicallyAssignDataEditorsTemplateSelector x:Key="DynamicallyAssignDataEditorsTemplateSelector" />
  <local:DataEditorsViewModel x:Key="DemoDataProvider" />

  <DataTemplate x:Key="DescriptionTemplate">
    <RichTextBox
      x:Name="descriptionRichTextBox"
      MinWidth="150"
      HorizontalContentAlignment="Stretch"
      Background="Transparent"
      BorderThickness="0"
      Foreground="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource TemplatedParent}}"
      IsReadOnly="True"
      IsTabStop="False" />
  </DataTemplate>
  <DataTemplate x:Key="descriptionTemplate">
    <RichTextBox
      x:Name="descriptionRichTextBox"
      MinWidth="150"
      HorizontalContentAlignment="Stretch"
      Background="Transparent"
      BorderThickness="0"
      Foreground="{Binding Path=(TextElement.Foreground), RelativeSource={RelativeSource TemplatedParent}}"
      IsReadOnly="True"
      IsTabStop="False" />
  </DataTemplate>

  <!-- 設(shè)置控件的全局樣式和數(shù)據(jù)綁定 -->
  <Style x:Key="DynamicallyAssignDataEditorsPropertyDefinitionStyle" TargetType="dxprg:PropertyDefinition">
    <Setter Property="Path" Value="{Binding Name}" />
    <!--<Setter Property="Header" Value="{Binding Converter={StaticResource PropertyDescriptorToDisplayNameConverter}}"/>-->
    <Setter Property="Description" Value="{Binding}" />
    <Setter Property="DescriptionTemplate" Value="{StaticResource descriptionTemplate}" />
  </Style>
  <Style x:Key="DescriptionContainerStyle" TargetType="dxprg:PropertyDescriptionPresenterControl">
    <Setter Property="ShowSelectedRowHeader" Value="False" />
    <Setter Property="MinHeight" Value="70" />
  </Style>

  <Style TargetType="Slider">
    <Setter Property="Margin" Value="2" />
  </Style>
  <Style TargetType="dxe:ComboBoxEdit">
    <Setter Property="IsTextEditable" Value="False" />
    <Setter Property="ApplyItemTemplateToSelectedItem" Value="True" />
    <Setter Property="Margin" Value="2" />
  </Style>

  <!-- 測(cè)試直接從DataTemplate獲取控件 -->
  <DataTemplate x:Key="SliderTemplate" DataType="local:SliderExtend">
    <!--<dxprg:PropertyDefinition>
      <dxprg:PropertyDefinition.CellTemplate>-->
    <!--<DataTemplate>-->
    <StackPanel x:Name="Root">
      <Slider
        Maximum="{Binding Path=Max}"
        Minimum="{Binding Path=Min}"
        Value="{Binding Path=Value}" />
      <TextBlock Text="{Binding Path=Value}" />
    </StackPanel>
    <!--</DataTemplate>-->
    <!--</dxprg:PropertyDefinition.CellTemplate>
    </dxprg:PropertyDefinition>-->
  </DataTemplate>

  <DataTemplate x:Key="ComboBoxEditItemTemplate" DataType="Tuple">
    <TextBlock
      Height="20"
      Margin="5,3,0,0"
      VerticalAlignment="Center"
      Text="{Binding Item1}" />
  </DataTemplate>
</ResourceDictionary>

2.編寫(xiě)對(duì)應(yīng)的模板選擇類 DynamicallyAssignDataEditorsTemplateSelector:

using DevExpress.Xpf.Editors;
using DevExpress.Xpf.PropertyGrid;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace PropertyGridDemo.PropertyGridControl
{
  public class DynamicallyAssignDataEditorsTemplateSelector : DataTemplateSelector
  {
    private PropertyDescriptor _property = null;
    private RootPropertyDefinition _element = null;
    private PropertyDataContext _propertyDataContext => App.PropertyGridDataContext;

    /// <summary>
    /// 當(dāng)重寫(xiě)在派生類中,返回根據(jù)自定義邏輯的 <see cref="T:System.Windows.DataTemplate" /> 。
    /// </summary>
    /// <param name="item">數(shù)據(jù)對(duì)象可以選擇模板。</param>
    /// <param name="container">數(shù)據(jù)對(duì)象。</param>
    /// <returns>
    /// 返回 <see cref="T:System.Windows.DataTemplate" /> 或 null。默認(rèn)值為 null。
    /// </returns>
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
      _element = (RootPropertyDefinition)container;
      DataTemplate resource = TryCreateResource(item);
      return resource ?? base.SelectTemplate(item, container);
    }

    /// <summary>
    /// Tries the create resource.
    /// </summary>
    /// <param name="item">The item.</param>
    /// <returns></returns>
    private DataTemplate TryCreateResource(object item)
    {
      if (!(item is PropertyDescriptor)) return null;
      PropertyDescriptor pd = (PropertyDescriptor)item;
      _property = pd;
      var customUIAttribute = (CustomUIAttribute)pd.Attributes[typeof(CustomUIAttribute)];
      if (customUIAttribute == null) return null;
      var customUIType = customUIAttribute.CustomUI;
      return CreatePropertyDefinitionTemplate(customUIAttribute);
    }

    /// <summary>
    /// Gets the data context.
    /// </summary>
    /// <param name="dataContextPropertyName">Name of the data context property.</param>
    /// <returns></returns>
    private object GetDataContext(string dataContextPropertyName)
    {
      PropertyInfo property = _propertyDataContext?.GetType().GetProperty(dataContextPropertyName);
      if (property == null) return null;
      return property.GetValue(_propertyDataContext, null);
    }

    /// <summary>
    /// Creates the slider data template.
    /// </summary>
    /// <param name="customUIAttribute">The custom UI attribute.</param>
    /// <returns></returns>
    private DataTemplate CreateSliderDataTemplate(CustomUIAttribute customUIAttribute)
    {
      DataTemplate ct = new DataTemplate();
      ct.VisualTree = new FrameworkElementFactory(typeof(StackPanel));
      ct.VisualTree.SetValue(StackPanel.DataContextProperty, GetDataContext(customUIAttribute.DataContextPropertyName));

      FrameworkElementFactory sliderFactory = new FrameworkElementFactory(typeof(Slider));
      sliderFactory.SetBinding(Slider.MaximumProperty, new Binding(nameof(SliderUIDataContext.Max)));
      sliderFactory.SetBinding(Slider.MinimumProperty, new Binding(nameof(SliderUIDataContext.Min)));
      sliderFactory.SetBinding(Slider.SmallChangeProperty, new Binding(nameof(SliderUIDataContext.SmallChange)));
      sliderFactory.SetBinding(Slider.LargeChangeProperty, new Binding(nameof(SliderUIDataContext.LargeChange)));
      sliderFactory.SetBinding(Slider.ValueProperty, new Binding(nameof(SliderUIDataContext.Value)));
      ct.VisualTree.AppendChild(sliderFactory);

      FrameworkElementFactory textFacotry = new FrameworkElementFactory(typeof(TextBlock), "TextBlock");
      textFacotry.SetValue(TextBlock.TextProperty, new Binding(nameof(SliderUIDataContext.Value)));
      //textBoxFactory.AddHandler(TextBox.IsVisibleChanged, new DependencyPropertyChangedEventHandler(SearchBoxVisibleChanged));
      ct.VisualTree.AppendChild(textFacotry);
      ct.Seal();
      return ct;
    }

    /// <summary>
    /// Creates the ComboBox edit template.
    /// </summary>
    /// <param name="customUIAttribute">The custom UI attribute.</param>
    /// <returns></returns>
    private DataTemplate CreateComboBoxEditTemplate(CustomUIAttribute customUIAttribute)
    {
      DataTemplate template = new DataTemplate();
      template.VisualTree = new FrameworkElementFactory(typeof(DockPanel));
      template.VisualTree.SetValue(DockPanel.DataContextProperty, GetDataContext(customUIAttribute.DataContextPropertyName));

      FrameworkElementFactory textFactory = new FrameworkElementFactory(typeof(TextBlock)) ;
      textFactory.SetValue(TextBlock.TextProperty, new Binding(nameof(ComboBoxEditDataContext.Name)));
      template.VisualTree.AppendChild(textFactory);

      FrameworkElementFactory comboBoxEditFactory = new FrameworkElementFactory(typeof(ComboBoxEdit));
      comboBoxEditFactory.SetBinding(ComboBoxEdit.ItemsSourceProperty, new Binding(nameof(ComboBoxEditDataContext.ItemSource)));
      comboBoxEditFactory.SetBinding(ComboBoxEdit.EditValueProperty, new Binding(nameof(ComboBoxEditDataContext.EditValue)));
      comboBoxEditFactory.SetBinding(ComboBoxEdit.SelectedIndexProperty, new Binding(nameof(ComboBoxEditDataContext.SelectedIndex)));
      comboBoxEditFactory.SetValue(ComboBoxEdit.ItemTemplateProperty, (DataTemplate)_element.TryFindResource("ComboBoxEditItemTemplate"));
      template.VisualTree.AppendChild(comboBoxEditFactory);
      template.Seal();
      return template;
    }

    /// <summary>
    /// Creates the property definition template.
    /// </summary>
    /// <param name="customUIAttribute">The custom UI attribute.</param>
    /// <returns></returns>
    private DataTemplate CreatePropertyDefinitionTemplate(CustomUIAttribute customUIAttribute)
    {
      DataTemplate dataTemplate = new DataTemplate();
      DataTemplate cellTemplate = null;//單元格模板
      FrameworkElementFactory factory = new FrameworkElementFactory(typeof(PropertyDefinition));
      dataTemplate.VisualTree = factory;
      switch (customUIAttribute.CustomUI)
      {
        case CustomUITypes.Slider:
          cellTemplate = CreateSliderDataTemplate(customUIAttribute); break;
          //cellTemplate = (DataTemplate)_element.TryFindResource("SliderTemplate");break;
        case CustomUITypes.ComboBoxEit:
          cellTemplate = CreateComboBoxEditTemplate(customUIAttribute);break;
        
      }

      if (cellTemplate != null)
      {
        factory.SetValue(PropertyDefinition.CellTemplateProperty, cellTemplate);
        dataTemplate.Seal();

      }
      else
      {
        return null;
      }
      return dataTemplate;
    }
  }
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace PropertyGridDemo.PropertyGridControl
{
  /// <summary>
  ///初始化所有屬性并調(diào)用模板選擇器進(jìn)行匹配
  /// </summary>
  public class DataEditorsViewModel
  {
    public IEnumerable<PropertyDescriptor> Properties { get { return TypeDescriptor.GetProperties(typeof(TestPropertyGrid)).Cast<PropertyDescriptor>(); } }
  }
}

3.編寫(xiě)一個(gè)可用于構(gòu)建模板的屬性 CustomUIType:

using System;

namespace PropertyGridDemo.PropertyGridControl
{
  public class CustomUIType
  {

  }

  public enum CustomUITypes
  {
    Slider,
    ComboBoxEit,
    SpinEdit,
    CheckBoxEdit
  }

  [AttributeUsage(AttributeTargets.Property)]
  internal class CustomUIAttribute : Attribute
  {
    public string DataContextPropertyName { get; set; }
    public CustomUITypes CustomUI { get; set; }
    /// <summary>
    /// 自定義控件屬性構(gòu)造函數(shù)
    /// </summary>
    /// <param name="uiTypes">The UI types.</param>
    /// <param name="dataContextPropertyName">Name of the data context property.</param>
    internal CustomUIAttribute(CustomUITypes uiTypes, string dataContextPropertyName)
    {
      CustomUI = uiTypes;
      DataContextPropertyName = dataContextPropertyName;
    }
  }

}

4.編寫(xiě)對(duì)應(yīng)的DataContext類 TestPropertyGrid:

using DevExpress.Mvvm.DataAnnotations;
using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Timers;
using System.Windows;

namespace PropertyGridDemo.PropertyGridControl
{
  [MetadataType(typeof(DynamicallyAssignDataEditorsMetadata))]
  public class TestPropertyGrid : PropertyDataContext
  {
    private double _count = 0;
    private SliderUIDataContext _countSource = null;
    private ComboBoxEditDataContext _comboSource = null;
    private double _value=1;

    public TestPropertyGrid()
    {
      Password = "1111111";
      Notes = "Hello";
      Text = "Hello hi";
    }

    [Browsable(false)]
    public SliderUIDataContext CountSource
    {
      get
      {
        if (_countSource != null)
        {

          return _countSource;
        }
        else
        {
          _countSource = new SliderUIDataContext(0, 100, Count, 0.1, 1);
          _countSource.PropertyChanged += (object o, PropertyChangedEventArgs e) =>
          {
            this.Count = _countSource.Value;
          };
          return _countSource;
        }
      }
    }

    [Browsable(false)]
    public ComboBoxEditDataContext ComboSource
    {
      get
      {
        if(_comboSource==null)
        {
          _comboSource =new ComboBoxEditDataContext(ComboBoxEditItemSource.TestItemSource,Value);
          _comboSource.PropertyChanged += (object o, PropertyChangedEventArgs e) =>
           {
             this.Value =Convert.ToDouble(_comboSource.EditValue.Item2); 
           };
          
        }
        return _comboSource;
      }
    }

    [Display(Name = "SliderEdit", GroupName = "CustomUI")]
    [CustomUI(CustomUITypes.Slider, nameof(CountSource))]
    public double Count
    {
      get => _count;
      set
      {
        _count = value;
        CountSource.Value = value; 
        RaisePropertyChanged(nameof(Count));
      }
    }

    [Display(Name = "ComboBoxEditItem", GroupName = "CustomUI")]
    [CustomUI(CustomUITypes.ComboBoxEit, nameof(ComboSource))]
    public double Value
    {
      get => _value;
      set
      {
        if (_value == value) return;
        _value = value;
        //ComboSource.Value = value;
        RaisePropertyChanged(nameof(Value));
      }
    }

    [Display(Name = "Password", GroupName = "DefaultUI")]
    public string Password { get; set; }

    [Display(Name = "TextEdit", GroupName = "DefaultUI")]
    public string Text { get; set; }

    [Display(Name = "Notes", GroupName = "DefaultUI")]
    public string Notes { get; set; }


    [Display(Name = "Double", GroupName = "DefaultUI")]
    [DefaultValue(1)]
    public double TestDouble { get; set; }

    [Display(Name = "Items", GroupName = "DefaultUI")]
    [DefaultValue(Visibility.Visible)]
    public Visibility TestItems { get; set; }
  }

  public static class DynamicallyAssignDataEditorsMetadata
  {
    public static void BuildMetadata(MetadataBuilder<TestPropertyGrid> builder)
    {
      builder.Property(x => x.Password)
        .PasswordDataType();

      builder.Property(x => x.Notes)
        .MultilineTextDataType();
    }
  }
}

 該類中用到的其他類主要有以下幾個(gè),以下幾個(gè)類主要用于數(shù)據(jù)綁定:

 namespace PropertyGridDemo.PropertyGridControl
{
  public class SliderUIDataContext:PropertyDataContext
  {
    private double _value = 0;
    private double _max = 0;
    private double _min = 0;
    private double _smallChange = 1;
    private double _largeChange=1;

    public SliderUIDataContext()
    {

    }

    /// <summary>
    /// Initializes a new instance of the <see cref="SliderUIDataContext"/> class.
    /// </summary>
    /// <param name="min">The minimum.</param>
    /// <param name="max">The maximum.</param>
    /// <param name="value">The value.</param>
    /// <param name="smallChange">The small change.</param>
    /// <param name="largeChange">The large change.</param>
    public SliderUIDataContext(double min, double max, double value,double smallChange=0.01,double largeChange=0.1)
    {
      SmallChange = smallChange;
      LargeChange = largeChange;
      Max = max;
      Min = min;
      Value = value;
    }

    /// <summary>
    /// Gets or sets the small change.
    /// </summary>
    /// <value>
    /// The small change.
    /// </value>
    public double SmallChange
    {
      get => _smallChange;
      set
      {
        if (value == _min) return;
        _min = value;
        RaisePropertyChanged(nameof(SmallChange));
      }
    }

    /// <summary>
    /// Gets or sets the large change.
    /// </summary>
    /// <value>
    /// The large change.
    /// </value>
    public double LargeChange
    {
      get => _largeChange;
      set
      {
        if (Value == _largeChange) return;
        _largeChange = value;
        RaisePropertyChanged(nameof(LargeChange));
      }
    }


    /// <summary>
    /// Gets or sets the maximum.
    /// </summary>
    /// <value>
    /// The maximum.
    /// </value>
    public double Max
    {
      get => _max;
      set
      {
        if (value == _max) return;
        _max = value;
        RaisePropertyChanged(nameof(Max));
      }
    }

    /// <summary>
    /// Gets or sets the minimum.
    /// </summary>
    /// <value>
    /// The minimum.
    /// </value>
    public double Min
    {
      get => _min;
      set
      {
        if (value == _min) return;
        _min = value;
        RaisePropertyChanged(nameof(Min));
      }
    }

    /// <summary>
    /// Gets or sets the value.
    /// </summary>
    /// <value>
    /// The value.
    /// </value>
    public double Value
    {
      get => _value;
      set
      {
        if (value == _value) return;
        _value = value;
        RaisePropertyChanged(nameof(Value));
      }
    }
  }
}
using System;
using System.Linq;

namespace PropertyGridDemo.PropertyGridControl
{
  public class ComboBoxEditDataContext:PropertyDataContext
  {
    private Tuple<string, object>[] _itemSource;
    private Tuple<string, object> _editValue;
    private int _selectedIndex;

    /// <summary>
    /// Initializes a new instance of the <see cref="ComboBoxEditDataContext"/> class.
    /// </summary>
    /// <param name="itemSource">The item source.</param>
    /// <param name="editValue">The edit value.</param>
    public ComboBoxEditDataContext(Tuple<string,object>[] itemSource,Tuple<string,object> editValue)
    {
      _itemSource = itemSource;
      _editValue = _itemSource.FirstOrDefault(x => x?.Item1.ToString() == editValue?.Item1.ToString() && x?.Item2?.ToString() == x?.Item2?.ToString());
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="ComboBoxEditDataContext" /> class.
    /// </summary>
    /// <param name="itemSource">The item source.</param>
    /// <param name="value">The value.</param>
    public ComboBoxEditDataContext(Tuple<string, object>[] itemSource, object value)
    {
      _itemSource = itemSource;
      _editValue = _itemSource.FirstOrDefault(x => x?.Item2.ToString() == value.ToString() );
    }

    public string Name
    {
      get;set;
    }

    /// <summary>
    /// Gets or sets the item source.
    /// </summary>
    /// <value>
    /// The item source.
    /// </value>
    public Tuple<string,object>[] ItemSource
    {
      get => _itemSource;
      set
      {
        //if (_itemSource == value) return;
        _itemSource = value;
        RaisePropertyChanged(nameof(ItemSource));
      }
    }

    /// <summary>
    /// Gets or sets the edit value.
    /// </summary>
    /// <value>
    /// The edit value.
    /// </value>
    public Tuple<string,object> EditValue
    {
      get => _editValue;
      set
      {
        if (_editValue == value) return;
        _editValue = value;
        RaisePropertyChanged(nameof(EditValue));
      }
    }

    public object Value
    {
      set
      {
        EditValue = ItemSource.FirstOrDefault(x => x.Item2.Equals(value));
      }
    }

    /// <summary>
    /// Gets or sets the index of the selected.
    /// </summary>
    /// <value>
    /// The index of the selected.
    /// </value>
    public int SelectedIndex
    {
      get => _selectedIndex;
      set
      {
        if (_selectedIndex == value || value==-1) return;
        _selectedIndex = value;
        EditValue = ItemSource[value];
        RaisePropertyChanged(nameof(SelectedIndex));
      }
    }
  }
}
using System.ComponentModel;

namespace PropertyGridDemo.PropertyGridControl
{
  public class PropertyDataContext:INotifyPropertyChanged
  {
    /// <summary>
    /// 在更改屬性值時(shí)發(fā)生。
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// 觸發(fā)屬性變化
    /// </summary>
    /// <param name="propertyName"></param>
    public virtual void RaisePropertyChanged(string propertyName)
    {
      PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
  }
}
using System;

namespace PropertyGridDemo.PropertyGridControl
{
  internal static class ComboBoxEditItemSource
  {
    internal static Tuple<string, object>[] TestItemSource = new Tuple<string, object>[] {
      new Tuple<string, object>("1",1),
      new Tuple<string, object>("2",2),
      new Tuple<string, object>("3",3)
    };
  }
}

5.將以上的CustomPropertyGrid丟進(jìn)容器中即可,這里我直接用Mainwindow來(lái)演示:

<Window
  x:Class="PropertyGridDemo.MainWindow"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:PropertyGridControl="clr-namespace:PropertyGridDemo.PropertyGridControl"
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  xmlns:local="clr-namespace:PropertyGridDemo"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  Title="MainWindow"
  Width="525"
  Height="350"
  WindowState="Maximized"
  mc:Ignorable="d">
  <Grid Margin="10">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="259*" />
      <ColumnDefinition Width="259*" />
    </Grid.ColumnDefinitions>

    <TextBox
      x:Name="OutputBox"
      Grid.ColumnSpan="1"
      HorizontalScrollBarVisibility="Auto"
      ScrollViewer.CanContentScroll="True" />
    <PropertyGridControl:CustomPropertyGrid x:Name="PropertyGrid" Grid.Column="1" />
  </Grid>
</Window>

運(yùn)行示意圖:

如何在PropertyGrid中自定義控件

上述內(nèi)容就是如何在PropertyGrid中自定義控件,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

文章題目:如何在PropertyGrid中自定義控件
網(wǎng)站網(wǎng)址:http://muchs.cn/article44/ghjche.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、云服務(wù)器品牌網(wǎng)站制作、網(wǎng)站建設(shè)、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司