c# - 使用 MVVM 实现搜索功能

标签 c# .net wpf mvvm

我正在将 C# WPF 应用程序转换为 MVVM 模式并有几个问题:

我有一个 ViewModel 绑定(bind)到带有构造函数的模型,该构造函数需要参数,该参数是从返回到搜索查询的 JSON 列表中选择单个对象的结果。
我想这意味着在执行搜索之前我无法实例化这个 ViewModel。

以前这不是问题,因为我不需要将 View 数据绑定(bind)到 ViewModel,并且只在所有数据都到位并且我准备好用它做某事时从 GUI 收集文本值来实例化对象(模型) .

对于 MVVM,这是一个问题,因为我不想强制此搜索成为第一个用户操作——用户应该能够修改绑定(bind)到 ViewModel 的 GUI 中的任何字段。

处理这种情况的一些实用方法是什么?似乎我必须要么:a)在实例化 VM 之前等待选择搜索结果,或者 b)从构造函数中删除参数,而是创建一个将在实例化的 VM 上调用的方法,以计算/设置否则由构造函数设置。

第二个问题:如何实现搜索功能——即点击搜索按钮后如何暂存结果列表?以前我会反序列化 SearchButton_Click 方法中的列表,并将组合框的绑定(bind)设置为结果集合。使用 MVVM,我无法描绘返回结果列表和选择单个结果之间的状态。我是否创建一个单独的 ViewModel,其中包含绑定(bind)到组合框的目标类型的空列表和绑定(bind)到搜索文本框的 SearchTerm 属性,并从 SearchButton 命令 ICommand 填充组合框?然后如何将所选项目绑定(bind)到我的原始 View 模型?

View 模型:

class ObjectViewModel
{
    public CustomObject data;
    public ICommand Search;

    public ObjectViewModel()
    {
        this.data = new CustomObject();
    }
}

模型:
[DataContract]
public class User
{
    [DataMember(Name = "EmailAddress")]
    public string EmailAddress { get; set; }
    [DataMember(Name = "FirstName")]
    public string FirstName { get; set; }
    [DataMember(Name = "FullName")]
    public string FullName { get; set; }
    ...
}


[DataContract]
public class CustomObject
{
    public User Owner;
    ...
}

查看(尚未重写):
<TextBox Margin="5,0" Name="Owner"></TextBox>
<Button Name="Search" Content="Lookup" Click="OwnerLookUp_Click"></Button>
<ComboBox Name="OwnerMatches" SelectionChanged="OwnerMatches_SelectionChanged" Visibility="Hidden"/>

OwnerLookUp_Click 从 Owner 文本框中获取文本并返回 ObservableCollection 并将其绑定(bind)到 OwnerMatches。 OwnerMatches_SelectionChanged 将 Owner 文本框设置为所选项目的 Fullname 属性。

在这种情况下,我要绑定(bind)到 ObjectViewModel 中的 data.Owner 什么?

最佳答案

您的 View 模型应该代表您的 View 的业务逻辑和状态。所以关于你的第一个问题,如果它是你对 的看法的有效状态不是 有一个搜索,那么它不应该是 View 模型的构造函数参数。相反,它可能应该是一个属性。

通常在 WPF 中,您会通过命令将按钮绑定(bind)到某种 ICommand。在您的 View 模型上(我通常使用 DelegateCommand )。该命令应该执行搜索,然后适本地更新 View 模型的状态。意思是,它应该进行搜索,收集结果,并使用它收集的数据设置与搜索结果相关的属性值。

这样做的好处是,假设您有一些 UI 组件绑定(bind)到这些搜索结果,一旦您的命令完成,您的 UI 就会自动刷新结果,而无需额外的代码。

更新

回应您的评论:一切都应该绑定(bind)到您的 View 模型,并且您的 View 模型使用这些绑定(bind)来完成所需的工作并更新 View 。

所以你的文本框Owner应该绑定(bind)到一个属性,然后你的 ICommand看起来像这样:

private void ClickCommandExecute() 
{
      var results = searchHelper.SearchFor(this.Owner);
      this.ComboSource = results;
}

同样,您的组合框的 SelectedValue属性将绑定(bind)到 View 模型上的另一个属性。在您的属性的 setter 中,您可以对选择更改使用react:
public string SelectedResult
{
    get { ... }
    set 
    {
        _selectedResult = value;
        OnSelectedResultChanged(); // Go do what you need to do here
    }
 }

关于c# - 使用 MVVM 实现搜索功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18749597/

相关文章:

c# - Windows.UI.Xaml.dll 中的应用程序内部异常

c# - C# 中的 BigInteger 除法

mysql - vb.net 应用程序在新设置的计算机上安装后性能下降

c# - 类声明中的只读关键字

c# - 无法在 C# 中使用 twilio 发送短信

wpf - 获取路径或多段线上最接近断开点的点

c# - WPF 的 ICollectionView.filter 具有大量数据

c# - 为什么 Unity 在 Mono 支持 .NET 3.5 时使用 .NET 2.0?

c# - 相同的 ItemSource,但每个列表框都有另一个 View

C# 编程错误 - 表达式表示 `type',其中应为 `variable'、 `value' 或 `method group'