ViewModel properties for properties of nested classes inside the model

1.1k views Asked by At

I have an application following the MVVM pattern, that has to serialize XML files. As some of the XML attributes are nested, I've created nested classes inside my Model, like this:

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

The attributes of the nested classes are all strings, because this simplifies the XML serialization for now (I'm still in the conception phase).

In my corresponding ViewModel, I've simply created a property for the nested class inside the model, so I can access all of the nested properties with just referring to this nested class from the 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(); }
}

The question is, however, that I want to display some of the properties not as strings but as boolean values using checkboxes on the UI.

Saying I want to display Model.oper.vin.vin_1 as boolean (where the ViewModel should manage the conversion from string to bool in the getter of its own property reflection of Model.oper.vin.vin_1), how would I do that?

Would I really have to implement every nested property from a nested class as an own property of the ViewModel (like stated below) to gain control over the way it will be returned to the 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"; }
    }
}

I hope there is a better solution out there...


Edit:

What I forgot to mention before, there're not only strings that have to be displayed as booleans, also DateTime-values that should be displayed as a DatePicker-control, integer-values that I would like to have as NumberPickers and so on.

The xml-file, on the other hand, will be consumed by an interface with some pretty fixed regulations that i need to match, such a dynamically leading zeros on both integer- and float-values, special date formats and commas instead of dots as decimal separators. So sticking with the string-values inside the object to serialize is a good way of maintaining control over how the values would get actually parsed inside the xml-file.

I'll try and experiment with some different converters, as @BrandlyDOTNet reommended, but are still curious about how this could be solved in another way.

1

There are 1 answers

1
BradleyDotNET On BEST ANSWER

There's a different solution out there, namely that you can use a converter to define the translation between your strings and a bool.

Something like:

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

   public object ConvertBack(...)
   {
       bool boolVal = (bool)value;
       return boolVal ? "1" : "0";
   }
}

Usage:

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

But to answer your deeper question, no, the framework will not just convert the string "1" into a bool. Moreover, you can strongly type your object that is being serialized, so none of this is actually necessary.