WPF:将标签绑定到类属性

29
我尝试将标签的内容绑定到类实例的字符串属性,但并没有取得太大成功。
XAML:
<Window x:Class="WPFBindingTest.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>        
    <Label Height="28" Margin="12,55,106,0" Name="label1" Background="Bisque"
           Content="{Binding Source=MyFoo, Path=W1}" VerticalAlignment="Top" />

    <Label Height="28" Margin="12,12,106,0" Name="label2" Background="Bisque"
           Content="{Binding Source=MyFoo, Path=W2}"  VerticalAlignment="Top" />

    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,32,48"
            Name="button1" VerticalAlignment="Bottom" Width="89"
            Click="button1_Click">
        Set Properties
    </Button>

</Grid>   
</Window>

C#:

namespace WPFBindingTest
{
   public partial class Window1 : Window
    {
        public Foo MyFoo;

        public Window1()
        {
            InitializeComponent();            

            MyFoo = new Foo();           
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {      
            MyFoo.W1 = "Hello";
            MyFoo.W2 = "Dave";
        }
    }

    public class Foo
    {
        public string W1 { get; set; }
        public string W2 { get; set; }
    }
}

即当我点击按钮时,我设置MyFoo的属性为“Hello”和“Dave”,并希望在UI标签上反映出来。 我已经将Content设置为绑定,但是有些不对劲。 我在这里做错了什么?

2个回答

24

你可以将MyFoo设置为依赖属性,并将DataContext设置为Window1的实例:

<Window DataContext="{Binding RelativeSource={RelativeSource Self}}" ...>

查看此文章了解更多细节。

MyFoo变为依赖属性并非强制性要求,如果你在分配DataContext之前设置属性值,(但不能使用字段。)则仅使用属性可能有效。但是,如果希望标签捕获W1W2的变化值(或者不知道/不关心值是在分配DataContext之前还是之后设置的),则需要将Foo设置为DependencyObject或实现接口INotifyPropertyChanged


1
谢谢,这指引了我正确的方向。我让Foo实现了INotifyPropertyChanged接口,然后将Window1的DataContext设置为BindingList<Foo>中包含MyFoo的内容。标签内容现在是:{Binding Path=W1, UpdateSourceTrigger=PropertyChanged}现在它完美地工作了! - Gareth
2
@Vlad,使用DependencyProperty和实现INotifyPropertyChanged之间有什么区别?或者这应该是一个单独的问题? - ywm
@ymw:这是一个不同的问题,实际上相当大。简而言之:两者都适用于仅绑定,但INotifyPropertyChanged更轻量级,DependencyProperty如果未使用则不占用内存,并且可以用于动画、样式、模板,可以被继承(从父容器到包含的元素)等等。例如,请参见此答案 - Vlad
@Vlad 我知道这是6年前的事了,但你必须得到赞赏,因为你给出了一个清晰、简洁、更重要的是易于理解的答案。我不知道为什么那么多人很难以清晰简单的方式描述WPF UI元素绑定,但你在这里做到了! - Redgum

15

或者给你的窗口起一个名称:比如NameOfWindow,然后使用 ElementName 绑定:

Content="{Binding ElementName=NameOfWindow, Path=MyFoo.W1}"

完整的 XAML 示例:

<Window x:Class="WPFBindingTest.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" Name="NameOfWindow">    
<Grid>        
    <Label Height="28" Margin="12,55,106,0" Name="label1" Background="Bisque" Content="{Binding ElementName=NameOfWindow, Path=MyFoo.W1}" VerticalAlignment="Top" />
    <Label Height="28" Margin="12,12,106,0" Name="label2" Background="Bisque" Content="{Binding ElementName=NameOfWindow, Path=MyFoo.W2}"  VerticalAlignment="Top" />
    <Button Height="23" HorizontalAlignment="Right" Margin="0,0,32,48" Name="button1" VerticalAlignment="Bottom" Width="89" Click="button1_Click">Set Properties</Button>
</Grid> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接