【问题标题】:Binding via C# not updating通过 C# 绑定不更新
【发布时间】:2018-06-21 17:57:04
【问题描述】:

我正在使用 MVVM 原则为 UWP 创建一个应用程序。

我有一个包含标准工具栏的页面,其下方的 ScrollView 中的实际内容是动态的,具体取决于用户从哪里导航;

<ScrollViewer>
        <StackPanel Orientation="Vertical">
            <ContentControl HorizontalAlignment="Stretch" 
                            VerticalAlignment="Stretch" 
                            Content="{x:Bind viewModel.Content}">
            </ContentControl>
        </StackPanel>
</ScrollViewer>

我绑定到该部分的内容的简化版本如下所示:

public class Content : StackPanel
{
    ContentViewModel ViewModel;
    TextBlock txtInformation;

    public Content()
    {
        Orientation = Orientation.Vertical;
        ViewModel = new ContentViewModel();                        
        txtInformation = new TextBlock();

        txtInformation.SetBinding(TextBlock.TextProperty,
                                  new Binding()
                                  {
                                      Mode = BindingMode.OneWay,
                                      Source = ViewModel.Item,
                                      Path = new 
                                      PropertyPath("Information"),
                                      TargetNullValue = "No information found"
                                  });

        Children.Add(txtInformation);
    }
}

最后,以下是内容视图模型的简化版本:

public class ContentViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    MyObject _item;

    public ContentViewModel()
    {
        Item = new MyObject()
        {
            Information = "Information goes here"
        };  
    }

    public MyObject Item
    {
        get
        {
            return _item;
        }
        set
        {
            _item = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Item"));
        }
    }
}

最初绑定似乎有效,因为当页面加载时,TextBlock 的文本值是“未找到信息”。但是当属性更改时,UI 没有更新。

这似乎只是在使用 SetBinding() 方法在 C# 中设置控件的绑定而不是在使用 {x:Bind} 扩展名的 XAML 中设置控件的绑定时出现问题,因为我的其他页面使用 XAML 进行正确绑定更新。

不会抛出任何错误。

【问题讨论】:

  • “没有抛出错误” -- 甚至没有消息到调试输出?无论如何,您使用的是TextBox.TextProperty,即使绑定的目标对象是TextBlock。所以,我首先会尝试使用TextBlock.TextProperty。
  • 我的错,那是一个错字。发现得好!我没有检查太多输出,但会看看
  • 输出似乎没有显示有关该问题的任何有用信息。谢谢你的建议。
  • 如果您创建一个新的 UWP 项目并将您的示例写入其中,这将非常有帮助......然后将示例代码复制到您的问题中(大部分是完整的)。像public class ContentViewModel() 这样的东西意味着我不能相信你发布的代码无论如何都与问题有关。
  • 从 @grek40 开始,将这个示例项目放入 Github 并发送链接可能会很有用。这样其他人就可以在他们自己的机器上重现您的问题

标签: c# xaml mvvm binding uwp


【解决方案1】:

试试这样。我认为 INotifyPropertyChanged 接口的实现有问题。

public class Employee : INotifyPropertyChanged 
{
    private string _name;
    private string _organization;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            RaisePropertyChanged("Name");
        }
    }

    public string Organization
    {
        get { return _organization; }
        set
        {
            _organization = value;
            RaisePropertyChanged("Organization");
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;
    protected void RaisePropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}

【讨论】:

  • 感谢您的建议。我怀疑这是 INotifyPropertyChanged 接口的实现,因为我在绑定到成功更新的 XAML 视图的视图模型中使用相同的实现。无论如何我都尝试了,但不幸的是,没有成功。
  • 您的RaisePropertyChanged 实现比PropertyChanged?.Invoke 差,它不会解决问题。另见:stackoverflow.com/a/22268601/5265292
【解决方案2】:
Content="{x:Bind ViewModel.Content, Mode=Oneway}">

x:Bind 的标准模式是 OneTime... 仅在开始时有效...

【讨论】:

  • 感谢您的建议。但是我已经设置了 Mode = BindingMode.OneWay
【解决方案3】:

而不是

txtInformation.SetBinding(TextBlock.TextProperty,
                              new Binding()
                              {
                                  Mode = BindingMode.OneWay,
                                  Source = ViewModel.Item,
                                  Path = new 
                                  PropertyPath("Information"),
                                  TargetNullValue = "No information found"
                              });

Source & PropertyPath 属性应设置如下:

txtInformation.SetBinding(TextBlock.TextProperty,
                              new Binding()
                              {
                                  Mode = BindingMode.OneWay,
                                  Source = ViewModel,
                                  Path = new 
                                  PropertyPath("Item.Information"),
                                  TargetNullValue = "No information found"
                              });

感谢 @grek40 建议我在示例应用程序中重新创建问题。它澄清了错误的来源。

【讨论】:

    猜你喜欢
    • 2011-10-27
    • 2020-10-27
    • 1970-01-01
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多