簡體   English   中英

WPF中的數據綁定?

[英]DataBinding in WPF?

我正在嘗試在 WPF 中設置數據綁定。 我有類人,它通過一個文本框更新(類似老派),另一個文本框應該通過數據綁定反映對人對象的更改(它曾經是 type=twoway 但它拋出一個 xamlparse 異常)。 它不是這樣工作的,點擊顯示 person.name 的按鈕,它顯示正確的名稱,但文本框不會通過數據綁定更新。 這是嘗試理解數據綁定的糟糕方法嗎? 如果你有更好的建議來測試它,我完全可以放棄這段代碼並這樣做。

<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需要是一個屬性。

您遇到的下一個問題是,如果您希望在屬性更改時使用屬性值更新控件,則您的類必須實現屬性更改通知。 (這是Person.name必須是屬性的另一個原因。)

第三個問題是您在 WPF 應用程序中使用 WinForms 技術。 數據綁定消除了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屬性綁定到其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 數據綁定的功能遠不止這些,但這應該能讓您走上正軌。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM