简体   繁体   English

如何将文本框绑定到WPF中的类的字段?

[英]How to bind TextBox to field of a class in WPF?

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 ) (我从这里开始使用WpfPropertyGrid)

VectorEditor uses a DataTemplate like this: VectorEditor使用如下数据VectorEditor

<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. 在这种情况下,TextBox.Text中的Path设置为Value ,因为它是模板,所以它不知道此Item与哪个字段关联。

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 . 并绑定到它,因此,当此TextBox的值更改时,它可以向包含Float4的对象引发PropertyChanged事件。

There is at least two things that will prevent usage of your Float4 type in WPF: 至少有两件事会阻止在WPF中使用Float4类型:

  • 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: 在您的XAML中,您将能够进行以下两种方式的绑定:

<TextBox HorizontalAlignment="Stretch" Text="{Binding Path=Value.X}"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM