WPF:绑定属性到TextBlock不起作用 [英] WPF: Bind property to TextBlock not working

查看:147
本文介绍了WPF:绑定属性到TextBlock不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在xaml文件下面(有一个):

I have below xaml file (this a piece):

                        <Grid Opacity="1" Margin="5">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />                                
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />                                   
                            </Grid.ColumnDefinitions>

                            <Label Grid.Row="0" Grid.Column="0" Content="ID"/>
                            <Label Grid.Row="0" Grid.Column="1" Content="Name"/>
                            <Label Grid.Row="0" Grid.Column="2" Content="Description"/>                                

                            <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding ID}"/>
                            <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Name}"/>
                            <TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding Description}"/>

                        </Grid>

数据类之下:

public class Data : INotifyPropertyChanged
{        
    private string id= string.Empty;
    private string name = string.Empty;
    private string description = string.Empty;


    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged(String propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public string ID
    {
        get
        {
            return this.id;
        }

        set
        {
            if (value != this.id)
            {
                this.id = value;
                NotifyPropertyChanged("ID");
            }
        }
    }

    public string Name
    {
        get
        {
            return this.name;
        }

        set
        {
            if (value != this.name)
            {
                this.name = value;
                NotifyPropertyChanged("Name");
            }
        }
    }

    public string Description
    {
        get
        {
            return this.description;
        }

        set
        {
            if (value != this.description)
            {
                this.description = value;
                NotifyPropertyChanged("Description");
            }
        }
    }
}

xaml.cs 中,我实现了INotifyPropertyChanged:

Also in xaml.cs I implement INotifyPropertyChanged:

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

此外,在上述 xaml 我将按钮定义为:

Furthermore, in the above xaml I have a button defined as:

<Button Click="btn_Click"/>

,其实现在 xaml.cs 中,如下所示:

and the implementation for that is in xaml.cs as below:

    private void btn_Click(object sender, System.Windows.RoutedEventArgs e)
    {
      (DataContext as MyViewModel).SearchInDb('0303003'); // 0303003 -> this is only an example.
    }

在按钮上单击MyViewModel类上的一个方法,然后从该方法调用对数据库的查询,使用ID = 0303003。

On button click a method on MyViewModel class is called, and from there it invokes a query to database to retrieve data using ID = 0303003.

MyViewModel类下面(我仅显示方法):

Below MyViewModel class (I show only the method):

 public void SearchInDb(string id)
 {
      // request data to sql server database
      // and then populate a Data Class Object with the data retrieved
      // from database:

      Data = new Data(){                            
                ID = sReader[0].ToString().Trim(),
                Name = sReader[1].ToString().Trim(),
                Description = sReader[2].ToString().Trim()
             };
 }

注意:MyViewModel类未实现INotifyPropertyChanged。

Note: MyViewModel class does not implement INotifyPropertyChanged.

我的问题是以下

在上述方法 SearchInDb中填充新的Data对象后,网格中的标签未更新,它们保持为空。

After populating a new Data object within above method "SearchInDb", my labels in the grid are not updated, they remain empty.

推荐答案

您需要设置View的DataContext:

You need to set the View's DataContext:

View.xaml.cs

public View()
{
    InitializeComponent();
    this.DataContext = new MyViewModel();
}

但是您的摘要中还有其他一些问题。在 MVVM 方式中,它是 ViewModel ,它应该实现 INotifyPropertyChanged 。不是数据类。

But there is some other issues in your snippets. In the MVVM way, it is the ViewModel which is supposed to implements INotifyPropertyChanged. Not the data class.

这是应该的样子:

数据类

public class Data
{        
    public string Id {get;set;}
    public string Name {get;set;}
    public string Description {get; set;}
}

MyViewModel

public class MyViewModel : INotifyPropertyChanged
{        
    private Data _data;

    public string ID
    {
        get { return _data.Id;}
        set 
        {
            if(_data.Id != value)
            {
                _data.Id = value;
                NotifyPropertyChanged();
            }
        }
    }

    // Same stuff for the other properties

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyPropertyChanged([CallerMemberName]String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    public void SearchInDb(string id)
    {
        // request data to sql server database
        // and then populate a Data Class Object with the data retrieved
        // from database:

        _data = new Data()
        {                            
            Id = sReader[0].ToString().Trim(),
            Name = sReader[1].ToString().Trim(),
            Description = sReader[2].ToString().Trim()
        };

        NotifyPropertyChanged(nameof(ID));
        NotifyPropertyChanged(nameof(Name));
        NotifyPropertyChanged(nameof(Description));
    }
}

您的NotifyPropertyChanged代码没有错。这只是做旧的方法。这种方式更现代,不需要魔术字符串;-)。

There was nothing wrong with your NotifyPropertyChanged code. It is just an old way of doing it. This way is more modern and does not require magic strings ;-).

您还可以绑定 Command 依赖项通过在视图模型中使用Command属性将按钮的属性设置为 SearchInDb 方法。这样,您无需在后面的代码中编写代码。但这是另一个问题:D。

You can also bind the Command dependency property of your button to your SearchInDb methods by using a Command property in you view model. This way, you do not need to write code in your code behind. But that's another question :D.

并且您的View无需实现INotifyPropertyChanged(除非您的情况特别要求这样做)。

And there is no need for your View to implements INotifyPropertyChanged (unless your case specifically required this).

这篇关于WPF:绑定属性到TextBlock不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆