我正在使用WPF扩展工具包属性网格。我使用编辑器用户控件来显示对象列表,如下所示:
我的用户希望能够更改" Elements"中的数字。说明,并让代码调整列表中的元素数。
{删除了不完整的代码,请参阅下面的工作代码答案}
有没有办法让我自己的控制来取代标有“#34; 3元素"使用TextBox,我可以处理文本的更改并更改我的数组吗?
谢谢, 大卫
答案 0 :(得分:2)
好的,抱歉延迟,但这是我的问题的工作代码......我希望它可以帮到某人。
作为回顾,我想做的是产生一个看起来像这样的PropertyGrid条目:
总之,您需要做的是创建两个用户控件属性网格编辑器,一个用于摘要行(上面的旋转框和元素标签),另一个用于数据列表。所有相关代码如下:
首先,这里是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;
}
}
因此,您可以将任何Enumerable添加到Property网格