c# - WPF 中的数据绑定(bind)?

标签 c# wpf xaml data-binding

我正在尝试在 WPF 中设置数据绑定(bind)。我有类(class)人员,它通过一个文本框更新(类似老式),另一个文本框应该通过数据绑定(bind)将更改反射(reflect)到人员对象(它曾经是 type=twoway 但那扔了xamlparse 异常)。它不是那样工作的,点击显示 person.name 的按钮,它会显示正确的名称,但文本框不会通过数据绑定(bind)进行更新。这是尝试理解数据绑定(bind)的坏方法吗?如果您对测试它的方法有更好的建议,我完全可以放弃此代码并改为这样做。

<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 实现为一个字段。绑定(bind)不适用于字段。 Person.name 需要是一个属性。

您遇到的下一个问题是,如果您希望控件在属性更改时使用该属性的值进行更新,则您的类必须实现属性更改通知。 (这是 Person.name 必须是属性的另一个原因。)

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

第四个问题是不需要值转换,所以不需要实现值转换器。

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

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 属性绑定(bind)到它的 Name 属性,它们都会保持同步,例如:

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

WPF 数据绑定(bind)的内容远不止于此,但这应该能让您走上正轨。

关于c# - WPF 中的数据绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6414952/

相关文章:

wpf - 为什么我的命令绑定(bind)没有触发?

wpf - Microsoft.Win32.OpenFileDialog.ShowDialog() 何时返回 null?

c# - DataGrid SelectedItem 不更新

wpf - Powershell中的WPF网格高度降低

c# - Lucene.NET MoreLikeThis 例子

c# - 将 WPF 应用程序连接到 MySQL 数据库

android - Xamarin 表单中的 Prism 导航 - MasterDetailPage

c# - 从其他程序集实例化 ResourceDictionary xaml

c# - 我如何将数据集的表/对象列表发送到客户端应用程序?

c# - 推送到生产服务器时 ASP.NET MVC 错误 500