2008-10-17 39 views
1

好的...我是一个VB.NET WinForms家伙,试图理解WPF及其所有的迷人。我正在写一个基本的应用程序作为一种学习体验,并且已经阅读了大量的信息并观看了教程视频,但我无法用简单的DataBinding实现,并且我知道我错过了一些基本概念。尽管我很喜欢它,但我还没有那样“啊哈!”还没有审查源代码的时刻。数据绑定失败 - 帮我开始简单的例子

所以...在我的Window类中,我定义了一个自定义字符串Property。当我进入Blend时,我尝试将我的TextBox的文本绑定到这个属性,但是我的Property不会在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 

回答

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 =语法来更改单个绑定的数据源。

+0

谢谢,我会试试这个。 因此,关于绑定字符串“{Binding RelativeSource = {RelativeSource Self}}” 这可以在Blend中生成吗? VS会帮我用intellisense生成它吗?有没有什么方法可以让我发现这些东西的正确语法,还是我只需要记住它呢? – 2008-10-17 13:08:17

+0

我不认为Blend或VS在这些情况下非常有帮助。如果您有Resharper,它确实会在XAML中增加一点智能感知。 – 2008-10-17 13:59:13

5

对于数据绑定是有帮助的考虑几件事情:

  1. 源对象
  2. 目标对象(必须为DependencyObject)
  3. Source属性(在源对象的属性,它是参与结合)
  4. 目标属性(必须是一个依赖属性)

在您的示例代码:

  1. 源对象=窗口1
  2. 目标对象=文本框
  3. 来源属性= SomeText物业
  4. 目标属性=文本

绑定标记扩展那张目标对象的目标属性。

这里是一个图像,其示出了以上:

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不会更新。

我希望有帮助。

/// <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!"; 
    } 
} 
0

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

还有一个选择。不要使用.NET数据绑定,请考虑Update Controls .NET。这是一个替代数据绑定并且不需要INotifyPropertyChanged的开源项目。更新控件的好处是可以看到中间业务逻辑。使用INotifyPropertyChanged,您必须捕获并重新触发事件。