I am trying to create a custom property editor for vector value like this:
public struct Float4
{
public float x,y,z,w;
}
In some object, it will have a property like this:
public class SomeEntity : INotifyPropertyChanged
{
private Float4 prop;
[Category("Property")]
[Editor(typeof(VectorEditor),typeof(PropertyValueEditor)]
public Float4 Prop
{
get{return prop;}
set{prop = value ; NotifyPropertyChanged("prop");}
}
}
(I am using the WpfPropertyGrid from here )
VectorEditor
uses a DataTemplate like this:
<DataTemplate x:Key="VectorEditorTemplate">
<DataTemplate.Resources>
<!--first use a ObjectDataProvider to get a `Type`-->
<ObjectDataProvider MethodName="GetType" ObjectType="{x:Type local:Float4}" x:Key='VectorType' >
</ObjectDataProvider>
<local:GetFieldsConverter x:Key="GetFieldsConverter" />
</DataTemplate.Resources>
<!--then use a Converter to create a ObservableCollection of `FieldInfo` from `Type`-->
<ItemsControl ItemsSource="{Binding Source={StaticResource VectorType},Converter={StaticResource GetFieldsConverter}}">
<ItemsControl.Resources>
<!-- this Converter will provider field name-->
<local:GetFieldNameConverter x:Key="GetFieldNameConverter"/>
</ItemsControl.Resources>
<!-- Other Elements -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<DockPanel HorizontalAlignment="Stretch">
<TextBlock DockPanel.Dock='Left' Text="{Binding Converter={StaticResource GetFieldNameConverter}}" Width="25" />
<TextBox HorizontalAlignment="Stretch" Text="{Binding Path=Value}"/>
</DockPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
In this case, the Path in TextBox.Text is setted to Value
, since it is a template, it doesn't know which field this Item is associated with.
So, how to make it associated with the field? and binding to it, so when this TextBox's value changed, it can raise a PropertyChanged
event to the object which contains the Float4
.
There is at least two things that will prevent usage of your Float4
type in WPF:
it's a value type
the members are not properties but fields
So I fear you'll have to use a proxy for your values:
public class Float4Proxy : INotifyPropertyChanged
{
private Float4 float4;
public float X
{
get { return float4.x; }
set
{
if (value != float4.x)
{
float4.x = value;
PropertyChanged(this, new PropertyChangedEventArgs("X"));
}
}
}
...
}
And in your XAML you'll be able to do such two-way bindings:
<TextBox HorizontalAlignment="Stretch" Text="{Binding Path=Value.X}"/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.