数据绑定失败 - 帮助我开始使用简单的示例

时间:2008-10-17 11:47:38

标签: wpf data-binding

好的......我是一个试图理解WPF及其所有功能的VB.NET WinForms人。我正在编写一个基本的应用程序作为学习经验,并且已经阅读了大量信息和观看教程视频,但我无法通过简单的DataBinding开始,我知道我缺少一些基本概念。尽管我喜欢它,但我没有那个“啊哈!”审查源代码的时刻。

所以......在我的Window类中,我定义了一个自定义字符串Property。当我进入Blend时,我尝试将TextBox的文本数据绑定到此属性,但我的属性不会在Blend中显示为可用于绑定的内容。

有人可以告诉我我需要添加到我的代码/ XAML中吗?最重要的是为什么?

我的XAML:

<Window x:Class="Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <TextBox Text="How do I Bind my SomeText property here?"></TextBox>
    </Grid>
</Window>

我的窗口代码:

Class Window1 

    Private _sometext As String = "Hello World"

    Public Property SomeText() As String
        Get
            Return _sometext
        End Get
        Set(ByVal value As String)
            _sometext = value
        End Set
    End Property

End Class

4 个答案:

答案 0 :(得分:6)

以下是您需要更改XAML的方法(代码很好)。

<Window x:Class="Window1"    
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
            Title="Window1" Height="300" Width="300" 
            DataContext="{Binding RelativeSource={RelativeSource Self}}">    
      <Grid>        
          <TextBox Text="{Binding SomeText}">
          </TextBox>    
      </Grid>
    </Window>

要了解WPF中的绑定,您需要了解DataContext。每个元素都有一个DataContext属性,并且放在该属性中的任何对象都将成为未指定显式数据源的任何绑定的数据源。 DataContext的值继承自父对象(因此在这种情况下,TextBox继承Grid的DataContext,继承Window的DataContext)。由于您要引用窗口的属性,因此需要将DataContext设置为指向Window实例,这是我在Window的DataContext属性中所做的。

您还可以使用{Binding}元素中的Source =或RelativeSource =语法更改单个绑定的数据源。

答案 1 :(得分:5)

对于数据绑定,考虑以下几点是有帮助的:

  1. 源对象
  2. 目标对象(必须是DependencyObject)
  3. 源属性(参与绑定的源对象上的属性)
  4. 目标属性(必须是依赖属性)
  5. 在您的示例代码中:

    1. 源对象= Window1
    2. 目标对象=文本框
    3. Source Property = SomeText Property
    4. 目标属性=文字
    5. Binding标记扩展名在Target对象的Target属性上。

      这是一张说明以上内容的图片:

      alt text

      查看以下代码(解决此问题的一种方法):

      <Window
          x:Class="WpfApplication2.Window1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          x:Name="theWindow"
          Title="Window1"
          Height="300"
          Width="300"
      >
          <Grid>
              <StackPanel>
                  <TextBox Text="{Binding ElementName=theWindow, Path=SomeText}"/>
                  <Button
                      Width="100"
                      Height="25"
                      Content="Change Text"
                      Click="Button_Click"
                  />
              </StackPanel>
          </Grid>
      </Window>
      

      在Binding标记扩展中,我使用ElementName定义了源...这允许您使用可视树中的另一个元素作为源。在这样做的时候,我还必须给窗口一个带有x:Name属性的名称。

      有几种方法可以使用Binding定义源(即Source,ElementName,DataContext)...... ElementName只是一种方式。

      需要注意的一点是,Source属性不必是依赖属性,但如果不是,则Target属性将不会更新...没有一些特殊帮助。 看看下面这段代码(我道歉它是C#,对我来说更快)。在其中,您将看到我实现INotifyPropertyChanged。这允许源对象说某些内容已经发生变化......并且数据绑定足够智能以便观察它。因此,如果单击按钮(来自此处的示例代码),它将更新TextBox。如果不实现此接口(如果单击按钮),TextBox将不会更新。

      我希望有所帮助。

      /// <summary>
      /// Interaction logic for Window1.xaml
      /// </summary>
      public partial class Window1 : Window, INotifyPropertyChanged
      {
          public Window1()
          {
              InitializeComponent();
          }
      
          private string _someText = "Hello World!";
          public string SomeText
          {
              get { return _someText; }
              set
              {
                  _someText = value;
                  OnNotifyPropertyChanged("SomeText");
              }
          }
      
          #region INotifyPropertyChanged Members
      
          public event PropertyChangedEventHandler PropertyChanged;
          private void OnNotifyPropertyChanged(string propertyName)
          {
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
              }
          }
      
          #endregion
      
          private void Button_Click(object sender, RoutedEventArgs e)
          {
              this.SomeText = "Goodbye World!";
          }
      }
      

答案 2 :(得分:1)

WPF DataBinding是一个非常强大的功能。我建议阅读网上已有的一些文章,例如

对我来说非常有帮助Beatrix Costa's blog on Data Binding

答案 3 :(得分:0)

使用CLR属性进行数据绑定需要额外的步骤。您必须实现INotifyPropertyChanged并在CLR属性更改时触发PropertyChanged事件。这不会使它出现在Blend中,但您可以使用Text =“{Binding SomeText}”绑定到该属性,并将窗口的DataContext设置为您的对象。

还有另一种选择。不要使用.NET数据绑定,而应考虑Update Controls .NET。它是一个替代数据绑定的开源项目,不需要INotifyPropertyChanged。 Update Controls的优点在于它可以透视中间业务逻辑。使用INotifyPropertyChanged,您必须捕获并重新触发事件。