简体   繁体   English

简单的字符串属性似乎不会在XAML GUI中绑定

[英]Simple string property won't seem to bind in XAML GUI

I have a Page where I want to display a string property in a Label . 我有一个Page ,我想在Label显示string属性。 This is my code, but nothing will appear in the label. 这是我的代码,但是标签中什么也不会出现。

This is my .xaml 这是我的.xaml

<Page x:Class="MyProject.PageOne"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
          mc:Ignorable="d" 
          d:DesignHeight="300" d:DesignWidth="300"
        Title="PageOne"
          Name="pageOne>
    <Grid>
     <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    </Grid>
 <Label Grid.Column="0" Content="{Binding ElementName=pageOne, Path=aStr}" FontWeight="Normal" FontSize="43" HorizontalAlignment="Left" Margin="0,00,0,0" VerticalAlignment="Center" Foreground="White"/>
</Grid>

</Page>

And this is my .cs code 这是我的.cs代码

    public partial class PageOne: Page, IPageInterface
    {
       public String aStr{get;set;}
       public PageOne()
            {
                InitializeComponent();

            }
       public void Start()
         {
            aStr = "Test";

        }

    }

The only thing really wrong with the code you posted, in terms of the problem you describe, is that you have not implemented some way for property change notifications to occur. 就您所描述的问题而言,您发布的代码唯一真正的问题是您尚未实现某种方式来进行属性更改通知。 Because the aStr property is not set to the new value until after the Label content has been initially set, without a way to receive notification, the framework has no way to know it needs to update the Label content. 因为直到最初设置Label内容之后, aStr属性都不会设置为新值,否则无法接收通知,因此框架无法知道需要更新Label内容。

In WPF the two main ways this is typically done (indeed, AFAIK the only two fully supported ways) are to create DependencyProperty instances, or to implement INotifyPropertyChanged . 在WPF中,通常要完成的两种主要方法(实际上,只有AFAIK是仅有的两种完全受支持的方法)是创建DependencyProperty实例或实现INotifyPropertyChanged Either will work fine. 两者都可以正常工作。

Here is an example of how your code should look with INotifyPropertyChanged implemented: 这是实现INotifyPropertyChanged代码外观的示例:

public partial class PageOne : Page, IPageInterface, INotifyPropertyChanged
{
    private string _astr;
    public String aStr
    {
        get { return _astr; }
        set { _astr = value; OnPropertyChanged(); }
    }

    public Page1()
    {
        InitializeComponent();
    }

    public void Start()
    {
        aStr = "Test";
    }

    private void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Implementing the interface involves a couple of simple steps: 实施接口涉及几个简单步骤:

  1. Declare the event named PropertyChanged 声明名为PropertyChanged的事件
  2. Any time a property is changed, raise that event, passing the name of the property that's changing. 每当属性更改时,引发该事件,并传递要更改的属性的名称。

Note that to do this, you can't use auto-implemented properties. 请注意,您不能使用自动实现的属性。 You need to implement each property yourself, with a backing field, and a call to a method that will raise the property. 您需要自己实现每个属性,并具有一个后备字段,并调用将引发该属性的方法。

.NET offers the convenient [CallerMemberName] attribute, which I show here. .NET提供了方便的[CallerMemberName]属性,我在此处显示。 So in the setter method for your aStr property, after setting the backing field's value, you simply call the method without any parameters, and the runtime automatically fills in the correct property name for you. 因此,在aStr属性的setter方法中,设置背景字段的值后,您只需调用不带任何参数的方法,运行时就会自动为您填充正确的属性名称。


Now, the code you posted has some other problems as well, in the XAML. 现在,您发布的代码在XAML中也存在其他一些问题。 First it won't compile because you left out a " character, and because you've got an extra </Grid> closing tag. 首先,它不会编译,因为您省略了一个"字符,并且因为有一个额外的</Grid>结束标记。

One other possible problem, though it's not possible to know for sure since we are missing the full context of how you display this Page object, is that the text's color is white. 另一个可能的问题是,由于我们缺少显示此Page对象的完整上下文,因此无法确定,但该文本的颜色是白色。 If you're putting the Label instance on a white background, then of course you won't be able to see the text, even if it were set correctly. 如果将Label实例放在白色背景上,那么即使正确设置了文本,您当然也看不到。


I note that commenter Franck has suggested that you should set the DataContext . 我注意到评论者Franck建议您设置DataContext The truth is, given the code you posted this is actually not necessary, and doing so wouldn't actually fix the problem you are having. 事实是,鉴于您发布的代码实际上是不必要的,并且这样做实际上并不能解决您遇到的问题。

But if you do fix the underlying notification issue, then his suggestions are an alternative way that you can achieve the binding. 但是,如果您确实解决了基础通知问题,那么他的建议是实现绑定的另一种方法。 By setting the DataContext to the object containing the property (here, your PageOne class), then when you are binding you can just specify the property name alone, without having to include the ElementName at all, and without having to use the Path= with the property name. 通过将DataContext设置为包含该属性的对象(这里是PageOne类),然后在进行绑定时,您可以仅指定属性名称,而不必完全包含ElementName ,也不必使用Path=属性名称。 You may find this technique more convenient, at least some of the time. 至少在某些时候,您可能会发现此技术更方便。


In the future, please take the time to provide a good, minimal , complete code example that reliably reproduces the problem. 将来,请花一些时间提供一个良好, 最少完整的代码示例 ,以可靠地重现该问题。 You are more likely to get an answer that way, and you will ensure that any answer you do get is as good as it can be. 您更有可能以这种方式获得答案,并且将确保您得到的任何答案都尽可能地好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM