字符串属性和 Button.Content 的 WPF 绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3298674/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 21:57:05  来源:igfitidea点击:

WPF binding of string property and Button.Content

wpfdata-bindingobjectdataprovider

提问by Begtostudy

I want to bind string property with Button.Content.

我想将字符串属性与 Button.Content 绑定。

But why it didn't work?

但为什么它不起作用?

The data class:

数据类:

namespace test4
{
    public class Test : INotifyPropertyChanged
    {

         string   _Text = "Begin";

        public string Text
        {
            get{return _Text;}
            protected set { _Text = value; }
        }
        public void Start()
        {
            Text = "Begin";
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(Text));
        }
        public void End()
        {
            Text = "End";
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(Text));
        }


        public event PropertyChangedEventHandler PropertyChanged;
    }
}

The logical code:

逻辑代码:

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        test4.Test ttt = new test4.Test();
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

            System.Windows.Data.CollectionViewSource testViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("testViewSource")));
            testViewSource.Source = new object[]{ttt};
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (ttt.Text == "Begin")
                ttt.End();
            else
                ttt.Start();
        }
    }

The XAML:

XAML:

<Window x:Class="test5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:my="clr-namespace:test4" Loaded="Window_Loaded">
    <Window.Resources>
        <CollectionViewSource x:Key="testViewSource" d:DesignSource="{d:DesignInstance my:Test, CreateList=true}" />
    </Window.Resources>
    <Grid DataContext="{StaticResource testViewSource}">
        <Button Content="{Binding Path=Text, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Height="23" HorizontalAlignment="Left" Margin="158,95,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>

采纳答案by Nir

The quotes around Text in the call to the PropertyChangedEventArgs constructor are missing:

在对 PropertyChangedEventArgs 构造函数的调用中 Text 周围的引号丢失:

Text = "Begin";
if (PropertyChanged != null)
    PropertyChanged(this, new PropertyChangedEventArgs("Text"));

回答by HCL

PropertyChangedwants to see the name of the property that has changed and not the value. Change the event invocation to:

PropertyChanged想要查看已更改的属性的名称而不是值。将事件调用更改为:

PropertyChanged(this, new PropertyChangedEventArgs("Text")); 

and it will do the job. However I also would change the construction to

它会完成这项工作。但是,我也会将构造更改为

public string Text { 
     get{return _Text;} 
     protected set { 
          _Text = value; 
          if(null != PropertyChanged){
                 PropertyChanged(this,new PropertyChangedEventArgs("Text"));
          }   
     } 
} 

and then dont call the PropertyChanged-event from Start and End.

然后不要从开始和结束调用 PropertyChanged 事件。

And to go even a step further, create invocation-methods like:

更进一步,创建调用方法,如:

protected virtual void OnPropertyChanged(string propertyName) {
    OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}

protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
    if (null != PropertyChanged) {
        PropertyChanged(this,e);
    }
}

and then call them from your property-setter.

然后从您的属性设置器中调用它们。

回答by Begtostudy

First of all, I used objectdataproviding, but it is not the object "ttt", they are two different things.

首先,我使用了objectdataproviding,但它不是对象“ttt”,它们是两个不同的东西。

Second, PropertyChanged(this,new PropertyChangedEventArgs("Text"));"Text" is the name not the variable.

其次,PropertyChanged(this,new PropertyChangedEventArgs("Text"));“文本”是名称而不是变量。

So, the code is following, may be helpful to others.

因此,代码如下,可能对其他人有帮助。

The data class:

数据类:

namespace test3
{
    public class Test : INotifyPropertyChanged
    {

         string   _Text = "Begin";

        public string Text
        {
            get{return _Text;}
            protected set { _Text = value;
            NotifyPropertyChanged("Text");
            }
        }
        public void Start()
        {
            Text = "Begin";

        }
        public void End()
        {
            Text = "End";

        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        } 
    }
}

The logical cs:

逻辑 cs:

  public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            button1.DataContext=ttt;
        } 

        Test ttt = new Test();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (ttt.Text == "Begin")
                ttt.End();
            else
                ttt.Start();
        }
    }
}

The xaml:

xml:

<Window x:Class="test3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:test3"
        Title="MainWindow" Height="350" Width="525" >
    <Grid>
        <Button Content="{Binding Path=Text,UpdateSourceTrigger=PropertyChanged}" Height="23" HorizontalAlignment="Left" Margin="121,69,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
    </Grid>
</Window>

回答by Faenrig

You need to use quotes around the property:

您需要在属性周围使用引号:

public void Start()
{
    Text = "Begin";
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs("Text"));
}

I suggest to rather use the nameof()-method as you cannot rename the property while it's located between quotes:

我建议宁可使用 nameof() 方法,因为当属性位于引号之间时,您无法重命名该属性:

public void Start()
{
    Text = "Begin";
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(nameof(Text)));
}