【问题标题】:WPF: Bind property to TextBlock not workingWPF:将属性绑定到 TextBlock 不起作用
【发布时间】:2017-11-18 05:05:36
【问题描述】:

我有下面的 xaml 文件(这是一块):

                        <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:

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

此外,在上面的 xaml 我有一个按钮定义为:

<Button Click="btn_Click"/>

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

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

单击按钮时调用 MyViewModel 类上的一个方法,并从那里调用对数据库的查询以使用 ID = 0303003 检索数据。

MyViewModel 类下面(我只展示方法):

 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。

我的问题如下

在上述方法“SearchInDb”中填充一个新的数据对象后,我在网格中的标签没有更新,它们保持为空。

【问题讨论】:

  • 因此您为Data 属性分配了一个新值,UI 中没有任何反应。您没有向我们展示如何定义 Data。它会在其set 中提高PropertyChanged 吗?它是主视图模型的成员,对吧?其次,您不会在 XAML 中绑定到 Data 的任何属性。如果 Data 是您显示的 XAML 的 DataContext 的属性,并且如果您在它更改时引发 PropertyChanged,这应该可以工作:{Binding Data.ID}
  • 我看到 MVVM 的工作方式存在一些混乱,但首先,您是否设置了 View Datacontext ?
  • 这里缺少信息,我看不出您为什么或如何期望分配数据来更新网格中的标签?你在设置视图的 DataContext 吗?您如何将视图准确地绑定到数据?
  • 1) 点击edit 2) 在第一个代码块中选择 XAML 3) ctrl-k 直到缩进被修复 4) 谢谢我教你 ctrl-k

标签: c# wpf mvvm .net-3.5 inotifypropertychanged


【解决方案1】:

你需要设置View的DataContext:

View.xaml.cs

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

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

应该是这样的:

数据类

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 代码没有任何问题。这只是一种古老的做法。这种方式更现代,不需要魔术字符串;-)。

您还可以通过在视图模型中使用 Command 属性将按钮的 Command 依赖属性绑定到您的 SearchInDb 方法。这样,你就不需要在你的代码后面写代码了。但这是另一个问题:D。

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

【讨论】:

  • 在您提供的 MyViewModel 中,您永远不会调用 MyViewModel、ID、名称、描述中的属性。我正在使用带有 NET Framework 3.5 SP1 的 Visual Studio 2008。那么在 SearchInDb 方法中设置 new Data() 后如何调用 MyViewModel 中的属性呢?
  • 您在 XAML 中声明的绑定是“对属性的调用”
  • nameof 在 .NET 3.5 中不起作用,所以我改用字符串名称:"ID"、"Name"、"Description"
  • @user1624552 在这种情况下,我怀疑[CallerMemberName] 会起作用。我认为您将不得不像您在问题中所做的那样致电NotifyPropertyChangedNotifyPropertyChanged("ID")。你的问题解决了吗?
猜你喜欢
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-18
  • 1970-01-01
相关资源
最近更新 更多