模型中嵌套类属性的ViewModel属性

问题描述:

我有一个应用程序遵循MVVM模式,它必须序列化XML文件。由于一些XML属性的嵌套,我创建嵌套类我的模型里面,像这样:模型中嵌套类属性的ViewModel属性

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序列化(I” m仍处于概念阶段)。

在我相应的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复选框为布尔值。

说我要为布尔(其中视图模型应该管理从string转换为在Model.oper.vin.vin_1自有物业反射吸气bool)显示Model.oper.vin.vin_1,我会怎么做呢?

我是否真的必须实现嵌套类的每个嵌套属性作为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"; } 
    } 
} 

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


编辑:

什么我忘了之前提到,那里是不仅string S作显示为boolean s,也DateTime-应显示为DatePicker的值 - 控制,我希望作为NumberPicker的整数值和等等。和float - 值,特殊日期格式和逗号 -

的XML文件,而另一方面,将通过接口与一些非常固定的规则,我需要匹配,两个integer这样一个动态的前导零消耗而不是小数点分隔符。因此,坚持使用string-要在序列化对象内的值是维护对xml文件中的值进行实际解析的方式的一种好方法。

我会尝试尝试使用一些不同的转换器,因为@BrandlyDOTNet推荐,但仍然对如何以其他方式解决这个问题感到好奇。

有一个不同解决方案在那里,即可以使用转换器来定义你的字符串和布尔之间的转换。

喜欢的东西:

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” 变成了布尔。此外,你可以强制键入你正在被序列化的对象,所以这些都不是必要的

+0

*强调打字*你的意思是将所有这些'字符串'改为实际有用的数据类型,更好地匹配它们的值。随着项目的进展,我可以并且非常期待。但是我必须接受一个接口的特殊需求,这个接口是用来使用xml文件的,并且有一些我必须匹配的严格固定的格式规则。由于快速应用程序开发是一天的顺序,我希望现在可以坚持使用字符串变量,并找到一些可以减少写入代码量的东西。 所以我做了,谢谢你,我会看看这个'Converter'的东西。 – M463