WPF中的数据绑定? [英] DataBinding in WPF?

查看:93
本文介绍了WPF中的数据绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在WPF中设置数据绑定。我有一个班级人员,该人员通过一个文本框进行了更新(类似于oldschool),而另一个文本框应通过数据绑定将更改反映到人员对象(它以前是type = twoway的,但是扔了) xamlparseexception)。它不能那样工作,然后单击显示person.name的按钮并显示正确的名称,但文本框不会通过数据绑定更新。这是尝试理解数据绑定的不好方法吗?如果您有更好的建议来测试它,我完全可以放弃此代码,而是这样做。

I'm trying to get databinding set up in WPF. I've got the class person, which is updated (oldschool-like) through the one textbox, and the other textbox is supposed to mirror the change to the person object through a databinding (it used to be a type=twoway but that threw an xamlparseexception). It doesn't work like that, and hitting the button that shows the person.name and it shows the correct name but the textbox doesn't get updated via the databinding. Is this a bad way to try to understand databindings? If you've a better suggestion for a way to test it out I'm totally okay just ditching this code and doing that instead.

<Window x:Class="WpfApplication2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApplication2"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <local:PeoplePleaser x:Key="PeoplePleaser" />
</Window.Resources>
<Grid>
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    <TextBox Height="125" HorizontalAlignment="Left" Margin="81,122,0,0" Name="textBox1" VerticalAlignment="Top" Width="388" FontSize="36" Text="{Binding Converter={StaticResource PeoplePleaser}, Mode=OneWay}" />
    <TextBox Height="23" HorizontalAlignment="Left" Margin="209,39,0,0" Name="textBox2" VerticalAlignment="Top" Width="120" TextChanged="textBox2_TextChanged" />
</Grid>

public partial class MainWindow : Window
{
    public MainWindow()
    {
            InitializeComponent();
    }

    public static Person myPerson = new Person();
    private void button1_Click(object sender, RoutedEventArgs e)
    {
        MessageBox.Show(myPerson.name);
    }

    private void textBox2_TextChanged(object sender, TextChangedEventArgs e)
    {
       myPerson = new Person(textBox2.Text);
    }
}

public class Person
{
    public String name;

    public Person()
    {
        new Person("Blarg");
    }

    public Person(String args)
    {
        if (!args.Equals(null))
        {
            this.name = args;
        }
        else new Person();
    }

    public Person(String args, Person argTwo)
    {
        argTwo = new Person(args);
    }
}

public class PeoplePleaser : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            return MainWindow.myPerson.name;
        }
        catch (Exception e)
        {
            return "meh";
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (!value.Equals(null))
        {
            return new Person(value.ToString(), MainWindow.myPerson);
        }

        else
        {
        return(new Person("", MainWindow.myPerson));
        }
    }
}


推荐答案

这里有很多问题。

第一个也是最重要的一个是您实现了 Person.name 作为字段。绑定不适用于字段。 Person.name 必须是一个属性。

The first and probably most significant one is that you've implemented Person.name as a field. Binding doesn't work with fields. Person.name needs to be a property.

下一个问题是是否需要控件要在属性更改时使用属性的值进行更新,您的类必须实现属性更改通知。 (这是 Person.name 必须是属性的另一个原因。)

The next issue that you have is that if you want a control to be updated with the value of a property when that property changes, your class has to implement property-change notification. (Which is another reason that Person.name has to be a property.)

第三个问题是您在WPF应用程序中使用WinForms技术。数据绑定消除了 TextChanged 事件的大多数用例。 (并非全部:在开发自定义控件时会很有用。)

A third issue is that you're using WinForms techniques in a WPF application. Data binding eliminates most of the use cases for the TextChanged event. (Not all: it can be useful when you're developing custom controls.)

第四个问题是不需要价值转换,因此不需要实现价值

A fourth issue is there's no need for value conversion, so no need to implement a value converter.

正确实现属性更改通知的 Person 类应如下所示:

A Person class that implements property-changed notification correctly should look something like this:

public class Person : INotifyPropertyChanged
{
   public event PropertyChangedEventHandler PropertyChanged;

   private void OnPropertyChanged(string propertyName)
   {
      PropertyChangedEventHandler h = PropertyChanged;
      if (h != null)
      {
         h(this, new PropertyChangedEventArgs(propertyName));
      }
   }

   public Person() { }

   public Person(string name)
   {
      Name = name;
   }

   private string _Name = "I was created by the parameterless constructor";

   public string Name
   { 
      get { return _Name; }
      set
      {
         if (_Name == value)
         {
            return;
         }
         _Name = value;
         OnPropertyChanged("Name");
      }
   }
}

一旦完成此操作,如果您创建一个 Person 对象并绑定任何 TextBox 对象的 Text 属性更改为其 Name 属性,它们将全部保持同步,例如:

Once you've done this, if you create a Person object and bind any TextBox objects' Text properties to its Name property, they'll all be maintained in sync, e.g.:

<StackPanel>
   <StackPanel.DataContext>
      <local:Person Name="John Smith"/>
   </StackPanel.DataContext>
   <TextBox Text="{Binding Name, Mode=TwoWay}"/>
   <TextBox Text="{Binding Name, Mode=TwoWay}"/>
</StackPanel>

WPF数据绑定比这要多得多,但这应该可以使您顺利进行跟踪。

There's much, much more to WPF data binding than this, but this should get you going down the right track.

这篇关于WPF中的数据绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆