WPF扩展工具包属性网格 - 编辑ExpandableObject标题

时间:2014-07-08 20:53:51

标签: c# wpf xaml user-controls propertygrid

我正在使用WPF扩展工具包属性网格。我使用编辑器用户控件来显示对象列表,如下所示:

enter image description here

我的用户希望能够更改" Elements"中的数字。说明,并让代码调整列表中的元素数。

{删除了不完整的代码,请参阅下面的工作代码答案}

有没有办法让我自己的控制来取代标有“#34; 3元素"使用TextBox,我可以处理文本的更改并更改我的数组吗?

谢谢, 大卫

2 个答案:

答案 0 :(得分:2)

好的,抱歉延迟,但这是我的问题的工作代码......我希望它可以帮到某人。

作为回顾,我想做的是产生一个看起来像这样的PropertyGrid条目:

enter image description here

总之,您需要做的是创建两个用户控件属性网格编辑器,一个用于摘要行(上面的旋转框和元素标签),另一个用于数据列表。所有相关代码如下:

首先,这里是Element类:

public class Element 
{
    public Element(int number, double wtf)
    {
        Number = number;
        WTF = wtf;
    }

    public int Number { get; set; }

    public double WTF { get; set; }
}

我还有元素的视图模型:

public class ElementViewModel : XTRRABase
{
    public Element _element;

    public ElementViewModel(Element element)
    {
        _element = element;
    }

    public int Number
    {
        get { return _element.Number; }
        set { _element.Number = value; NotifyPropertyChanged(); }
    }

    public double WTF
    {
        get { return _element.WTF; }
        set { _element.WTF = value; NotifyPropertyChanged(); }
    }

    public String ElementInfo
    {
        get { return XTRRAApp.Application.AtomicElementList.GetElements()[Number]; }
        set { }
    }
}

ElementInfo属性返回元素名称(如示例中的“6(Carbon)”。)

在父视图模型(包含Elements属性的对象)中,属性如下所示:

    ElementListViewModel _elements;
    [PropertyOrder(4), DisplayName("Elements")]
    [ExpandableObject]
    [Editor(typeof(ElementHeaderUCEditor), typeof(ElementHeaderUCEditor))]
    public ElementListViewModel Elements
    {

        get { return (_elements = new ElementListViewModel(_material.Elements) ); }
        set {}
    }

请注意,此对象均为ExpandableObject,并且具有已定义的编辑器ElementHeaderUCEditor

ElementHeaderUCEditor定义IntegerUpDown旋转框和'elements'标签。这是XAML看起来像这样:

<UserControl x:Class="XTRRAApp.View.Editors.ElementHeaderUCEditor"
             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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit">
    <StackPanel Orientation="Horizontal" Background="White">
        <xctk:IntegerUpDown Text="{Binding Value.Count,UpdateSourceTrigger=PropertyChanged}" Width="100" Margin="2,2,2,2" ParsingNumberStyle="Integer"/>
        <Label Content="Elements" Width="Auto" Margin="2,2,2,2"/>
    </StackPanel>
</UserControl>

和代码隐藏:

public partial class ElementHeaderUCEditor : UserControl, ITypeEditor
{
    public ElementHeaderUCEditor()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(ElementListViewModel), typeof(ElementHeaderUCEditor),
                                                                    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public ElementListViewModel Value
    {
        get { return (ElementListViewModel)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public FrameworkElement ResolveEditor(Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyItem)
    {
        Binding binding = new Binding("Value");
        binding.Source = propertyItem;
        binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ElementHeaderUCEditor.ValueProperty, binding);
        return this;
    }
}

接下来,这是ElementListViewModel,它为List提供数据:

[DisplayName("Elements")]
public class ElementListViewModel : XTRRABase
{
    protected List<Element> _elements;

    public ElementListViewModel(List<Element> elements)
    {
        _elements = elements;
    }

    [Browsable(false)]
    public int Count
    {
        get { return _elements.Count; }
        set 
        { 
            while(value < _elements.Count)
            {
                _elements.RemoveAt(_elements.Count - 1);
            }
            while(value > _elements.Count)
            {
                _elements.Add(new Element(0,0));
            }
            NotifyPropertyChanged();
            NotifyPropertyChanged("Elements");
        }
    }

    [PropertyOrder(1), DisplayName("Elements")]
    [Editor(typeof(ElementUCEditor), typeof(ElementUCEditor))]
    public ObservableCollection<ElementViewModel> Elements
    {
        get
        {
            ObservableCollection<ElementViewModel> list = new ObservableCollection<ElementViewModel>();

            foreach(Element element in _elements)
            {
                list.Add(new ElementViewModel(element));
            }
            return list;
        }
        set { }
    }
}

XTRRABase只是我用来避免重复通知代码的常用基类:

public abstract class XTRRABase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

如你所见,使用另一个用户控件“ElementUCEditor”显示元素,它的XAML如下所示:

                                                                                                                                                                                                                                                                                                                                                                                                                                                                     

以及它的代码隐藏:

public partial class ElementUCEditor : UserControl, ITypeEditor
{
    public ElementUCEditor()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(ElementListViewModel), typeof(ElementUCEditor),
                                                                                    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    public ElementListViewModel Value
    {
        get { return (ElementListViewModel)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public FrameworkElement ResolveEditor(Xceed.Wpf.Toolkit.PropertyGrid.PropertyItem propertyItem)
    {
        Binding binding = new Binding("Value");
        binding.Source = propertyItem;
        binding.Mode = propertyItem.IsReadOnly ? BindingMode.OneWay : BindingMode.TwoWay;
        BindingOperations.SetBinding(this, ElementUCEditor.ValueProperty, binding);
        return this;
    }

}

答案 1 :(得分:0)

我使用了propertyGrid作为CustomEditor:

 boxes = [[1,2,20,20],[4,8,20,20],[8,10,40,40]]
 boxIDs = [1,2,3]


IDx = 2

XAML

public partial class PropertyGridEditor : ITypeEditor
{
    public PropertyGridEditor()
    {
        InitializeComponent();
    }

    public FrameworkElement ResolveEditor(PropertyItem propertyItem)
    {
        if (propertyItem.Value != null)
        {
            var objects = propertyItem.Value;
            foreach (var o in (IEnumerable)objects)
            {
                var propertyGrid = new Xceed.Wpf.Toolkit.PropertyGrid.PropertyGrid
                {
                    IsCategorized = false,
                    IsMiscCategoryLabelHidden = true,
                    ShowAdvancedOptions = false,
                    ShowDescriptionByTooltip = true,
                    ShowPreview = false,
                    ShowSearchBox = false,
                    ShowSortOptions = false,
                    ShowTitle = true,
                    ShowSummary = false,
                    SelectedObject = o,
                };
                Container.Children.Add(propertyGrid);
            }
        }

        return this;
    }
}

enter image description here

因此,您可以将任何Enumerable添加到Property网格