【问题标题】:XAML DataBinding ClarityXAML 数据绑定清晰度
【发布时间】:2017-04-04 21:35:18
【问题描述】:

想看看是否有人可以帮我解决这个问题?从 XAML 元素到 ViewModel(ex:1) 中的值,或从 CodeBehind(ex:2) 返回到元素,如... HostName.Text,DataBinding 是否有优势?

<TextBlock Text="{Binding HostName}" /> --- (ex:1)
<TextBlock Name="HostName" /> --- (ex:2)

离岸博彩

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Task;

namespace AppName.Models
{

public class Contact
{
    [Key]
    public int Id {get; set;}
    public string Team { get; set;}
    public string FirstName { get; set;}
    public string LastName { get; set;}
    public string Phone { get; set;}
    public string Email { get; set;}
    public string Role { get; set;}
    public string DisplayName => $"[LastName}, {FirstName}";
}
}

【问题讨论】:

  • 我不确定我是否完全理解这个问题。 Example1 是人们所说的数据绑定 - 视图模型属性绑定到控件的 Text 属性。当任一端的属性更改时,VM 支持属性会更新(如果您使用双向绑定并已实现 INotifyPropertyChanged)。示例 2 令人困惑。设置 HostName.Text 属性通常在您的代码隐藏文件中(但不是视图模型),但这不是数据绑定。从 ViewModel 执行此操作意味着您的视图模型需要了解您的视图和其中的特定文本块。这打破了 MVVM 模式。
  • 我修改了第二条语句以更好地反映您的更正...我想我想了解的是,您何时会选择一种方法而不是另一种方法?例如,ex:2 是否可以支持双向绑定.. 或者示例 2 甚至不被视为绑定?我以为是因为你没有绑定到 Control 的 Text 属性?

标签: c# xaml data-binding uwp


【解决方案1】:

简单的答案是它取决于您的应用程序和需求。当您构建一个小型应用程序时,使用代码隐藏或数据绑定来查看模型并没有太大的区别。很容易理解流程以及何时进行更新。但是随着您的应用程序复杂性的增加以及您需要测试您的代码,然后您开始使用使您的代码更易于维护和测试的模式。这就是 MVVM 模式的由来。

在您的代码隐藏文件中测试代码比仅在 ViewModel 类中测试您的业务逻辑并确保其按预期工作更难。

您上面的示例有点简单,因为它是一个仅显示文本且不接受输入的 TextBlock。 TextBox 是一个更好的绑定示例,因为数据可以在视图模型或 UI 中更改。绑定允许您使用属性支持显示的文本,因此从任何方向进行的更改都会自动更新模型属性和 UI。

<TextBox x:Name="Entry" Text="{Binding SelectedValue , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

视图模型:

public class CatalogViewModel : BindableBase
{
    private string selectedValue;
    public string SelectedValue
    {
        get { return selectedValue; }
        set { SetProperty<string>(ref selectedValue, value); }
    }
...
}

替代方案是代码隐藏文件中的大量代码,以保持 TextBox 和数据元素之间的同步。

<TextBox x:Name="Entry2" TextChanged="Entry2_TextChanged" />

后面的代码:

private string entryText;
public string EntryText
{
    get { return entryText; }
    set
    {
        if (value != entryText)
        {
            entryText = value;
            Entry2.Text = entryText;
        }
    }
}
private void Entry2_TextChanged(object sender, TextChangedEventArgs e)
{
    entryText = Entry2.Text;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
    // initialize controls
    EntryText = "Default";
}

您现在已经将您的业务逻辑与页面布局相结合,对其中任何一个的更改都会导致大量更改。而且测试代码的行为更难编写,也更难模拟。

如果有多个输入控件和更复杂的控件,例如 ListViews 和 GridViews,它只会变得更加复杂。

如果您对使用视图模型和数据绑定的好处感兴趣,您应该阅读 MVVM:https://msdn.microsoft.com/en-us/magazine/dd419663.aspx

【讨论】:

  • 很好的描述.. 是的,我正在构建更复杂的东西,并且确实想遵循 MVVM 逻辑。我已经浏览了许多在线教程并阅读了许多文章,随着时间的推移,我开始变得越来越清晰。我还没有一个啊哈时刻。例如,现在我的所有数据库表都以模型目录中的 POGO 对象表示。但我并不总是清楚地了解如何在 ViewModel 中表示它们。
  • 谢谢。您是否在 POCO 类中使用实体框架?模型和视图模型如何交互是 MVVM 中争论的话题。如果您正在编辑客户列表(例如),您是在 UI 绑定中公开该模型类还是将每个模型类包装在视图模型类中?我通常通过视图模型传递模式类(但不要复制它们)。所以我的 CustomerListViewModel 有一个属性 IList Customers 绑定到 XAML 中的 ListView。但这意味着您的模型类需要实现 INotifyPropertyChanged 才能正确支持数据绑定。
  • 我更新了我的原始帖子以包含一个对应于数据库表之一的 POCO 类。这在使用实体框架的 WebService 项目中也有重复。我尝试在我的主项目中使用它,但是当我发现目前无法通过 EF6 或 Core 与 SQL Server 同步时,我不得不走 WebService 路线。我想我可以从主项目中提取 EF Core 引用,因为它现在没有被使用。
猜你喜欢
  • 1970-01-01
  • 2014-01-31
  • 2015-11-23
  • 2012-11-14
  • 1970-01-01
  • 2011-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多