【问题标题】:ViewModel properties for properties of nested classes inside the model模型内嵌套类的属性的 ViewModel 属性
【发布时间】:2015-06-19 16:23:58
【问题描述】:

我有一个遵循 MVVM 模式的应用程序,它必须序列化 XML 文件。由于某些 XML 属性是嵌套的,因此我在模型中创建了嵌套类,如下所示:

public class OPER_FILE
{
    public UNB unb { get; set; }
    public OPER oper { get; set; }    //nested class, level 1

    public OPER_FILE()
    {
        unb = new UNB();
        oper = new OPER();
    }
}

public class OPER
{
    public UNH unh { get; set; }    //these are all nested classes, level 2
    public UVT uvt { get; set; }
    public VIN vin { get; set; }

    public OPER()
    {
        unh = new UNH();
        uvt = new UVT();
    }
}

#region "nested classes"
public class UNB
{
    public string unb { get; set; }
    public string unb_2 { get; set; }
}

public class UNH
{
    public string unh { get; set; }
    public string unh_2 { get; set; }
}

public class UVT
{
    public string uvt { get; set; }
    public string uvt_1 { get; set; }
    public string uvt_2 { get; set; }
}

public class VIN 
{
    public string vin { get; set; }
    public string vin_1 { get; set; }
    public string vin_2 { get; set; }
    public string vin_3 { get; set; }
    public string vin_4 { get; set; }
}
#endregion

嵌套类的属性都是字符串,因为这暂时简化了XML序列化(我还在构思阶段)。

在我对应的 ViewModel 中,我只是为模型内的嵌套类创建了一个属性,因此我可以通过从 ViewModel 中引用这个嵌套类来访问所有嵌套属性。

public class OPERViewModel : IViewModelBase
{
    private OPER_FILE Model;

    public UNB unb 
    { 
        get
        { return Model.unb;}
        set
        { Model.unb = value; }
    }

    public OPER oper
    {
        get
        { return Model.oper; }    //this is the tricky part, by now I'm just referring to the nested class as a property of the model
        set
        { Model.oper = value; }
    }

    public OPERViewModel()
    { Model = new OPER_FILE(); }
}

但是,问题是,我想使用 UI 上的复选框将某些属性显示为布尔值而不是字符串。

说我想将Model.oper.vin.vin_1 显示为布尔值(ViewModel 应该在Model.oper.vin.vin_1 的自身属性反射的getter 中管理从stringbool 的转换),我该怎么做?

我是否真的必须将嵌套类中的每个嵌套属性实现为 ViewModel 的自己的属性(如下所述)才能控制将其返回到 UI 的方式?

//ViewModel-implementation with type-conversion of a property from a nested class of the model
//this would get bind to the UI instead of Model.oper.vin.vin_1
public bool vin_1    
{
    get
    {
        if (Model.oper.vin.vin_1 == "1")
        { return true; }
        else
        { return false; }
    }
    set
    {
        if (value)
        { Model.oper.vin.vin_1 = "1"; }
        else
        { Model.oper.vin.vin_1 = "0"; }
    }
}

我希望有更好的解决方案...


编辑:

我之前忘记提到的,不仅strings 必须显示为booleans,还有DateTime-values 应该显示为DatePicker-control, integer-我想拥有的值是NumberPickers 等等。

另一方面,xml 文件将被具有一些我需要匹配的相当固定规则的接口使用,例如 integer- 和 float-values 上的动态前导零,特殊日期格式和逗号而不是点作为小数分隔符。因此,坚持使用对象内部的string-values 进行序列化是保持对如何在 xml 文件中实际解析值进行控制的好方法。

正如@BrandlyDOTNet 所建议的那样,我将尝试使用一些不同的转换器进行试验,但仍然对如何以另一种方式解决这个问题感到好奇。

【问题讨论】:

    标签: c# wpf mvvm nested-class


    【解决方案1】:

    有一个不同的解决方案,即您可以使用 converter 来定义字符串和布尔值之间的转换。

    类似:

    public class StringToBoolConverter : IValueConverter
    {
       public object Convert(...)
       {
           return value.ToString() != "0";
       }
    
       public object ConvertBack(...)
       {
           bool boolVal = (bool)value;
           return boolVal ? "1" : "0";
       }
    }
    

    用法:

    <CheckBox IsChecked={Binding SomeProp, Converter={StaticResource StringToBoolConverter}"/>
    

    但要回答你更深层次的问题,不,框架不会只是将字符串“1”转换为布尔值。此外,您可以强类型化正在序列化的对象,因此实际上都不需要

    【讨论】:

    • 我猜,通过强输入,你的意思是将所有strings 更改为实际有用的数据类型,更好地匹配它们的值。随着项目的进展,我可以并且强烈地等待必须这样做。但是我必须满足一个接口的特殊需求,该接口旨在使用 xml 文件,并且有一些我必须匹配的严格固定的格式规则。由于快速的应用程序开发已成为当务之急,我希望我现在可以坚持使用字符串变量并找到一些东西来减少要编写的代码量。所以我做到了,谢谢你,我会看看这个Converter-thing。
    猜你喜欢
    • 1970-01-01
    • 2019-10-14
    • 1970-01-01
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    • 1970-01-01
    相关资源
    最近更新 更多