0

我有一个 MVVM 应用程序,它有一个 WPF 网格,其中包含其他嵌入式 WPF 网格,同时,它们每个都包含一些字段(WPF TextBlocks)。

非常简化的示例 - 查看:

<Grid>

   <Grid>
       // Row definitions
       // Colum definitions
       <TextBlock Grid.Row="3" Grid.Column="0"
                  Text="{Binding Path=SomeField1}" /> 
   <Grid>

   <Grid>
       // Row definitions
       // Colum definitions
       <TextBlock Grid.Row="0" Grid.Column="1"
                  Text="{Binding Path=SomeField2}" /> 
   <Grid>

</Grid>

这些 TextBlock 中的每一个都绑定到视图模型中定义的字符串属性。

查看模型(它实现了 INotifyPropertyChanged)

private string _someField1;
public string SomeField1
{
   get return _someField1;
   set 
   {
       if (_someField1 == value) return;
       _someField1 = value;
       OnPropertyChanged("SomeField1");
   }
}

private string _someField2;
public string SomeField2
{
   get return _someField2;
   set 
   {
       if (_someField2 == value) return;
       _someField2 = value;
       OnPropertyChanged("SomeField2");
   }
}

然后我有一个模型,我的意思是,一个具有一些公共属性的类,一旦从设备获取数据,就会由一个进程填充。此类包含与视图模型中定义的属性完全相同的属性。

型号

public class MyModel
{
    private string _someField1;
    public string SomeField1
    {
       get return _someField1;
       set 
       {
           if (_someField1 == value) return;
           _someField1 = value;
       }
    }

    private string _someField2;
    public string SomeField2
    {
       get return _someField2;
       set 
       {
           if (_someField2 == value) return;
           _someField2 = value;
       }
    }
}

稍后从视图模型中,我从此类(模型)中提取数据,并将这些属性的值分配给视图模型中的匹配属性。最后,由于视图绑定到这些属性,因此视图正确更新为如下示例的值。

查看模型方法提取接收到的数据

private void DataReceived(MyModel data)
{
    this.SomeField1= data.SomeField1;
    this.SomeField2= data.SomeField2;
}

问题是我必须在视图模型和模型中定义两次属性。所以我想避免这种情况,我想将 Textblocks 直接绑定到模型中的属性,而不是在视图模型中定义属性以避免冗余代码。或者例如,是否有任何简单的方法可以将我的模型(MyModel)绑定到外部主网格,然后将文本框绑定到视图模型中的属性(在数据网格中绑定 itemsource 时类似)?

4

2 回答 2

0

我会建议一个通用的视图模型:

public class BaseViewModel<TModel>
{
    public TModel Model
    {
        get;
        private set;
    }

    public BaseViewModel(TModel model)
    {
        this.Model = model;
    }
}

然后你可以绑定到它:

<TextBlock Grid.Row="3" Grid.Column="0" Text="{Binding Path=Model.SomeField1}" />
于 2019-01-04T13:24:46.860 回答
0

我在想如果低于它还可以并尊重 MVVM 模式。在看到 c0d3b34n 提出的解决方案后,我想到了这一点。我认为它更简单,不需要做接口和通用视图模型。我已经检查过并且有效:

在视图模型中声明一个属性:

private MyModel _model;
public MyModel Model
{
    get { return _model; }
    set   
    {
         _model = value;
         OnPropertyChanged("Model");
    }
}

然后在视图中:

<TextBlock Grid.Row="3" Grid.Column="0" Text="{Binding Path=Model.SomeField1}" />

... 其余的 TextBlocks 也是如此。

最后:

 private void DataReceived(MyModel data)
 {
       this.Model = data;
 }

但正如 BionicCode 在评论中所说,这个解决方案打破了 MVVM 模式。

于 2019-01-04T15:17:23.940 回答