简体   繁体   中英

How can i bind xml to mvvm wpf?

I have a problem. I have wpf mvvm app and I need to bind xml, but I don't know how.

I have there elements model, elements vm, and a view. Everything work, but all of that elements have "some base" model.

class ItemModel
{
    public ItemModel(string name, double weight, double sg, double volume)
    {

        Name = name;
        Weight = weight;
        Sg = sg;
        Volume = volume;

    }

    public string Name { get; set; }
    public double Weight { get; set; }
    public double Sg { get; set; }
    public double Volume { get; set; }

}

This is my VM.

class ItemViewModel : BaseVM
{
    public ItemViewModel(string name, double sg, double weight,  double volume)
    {
        Name = name;
        Weight = weight;
        Sg = sg;
        Volume = volume;

    }

    public string Name { get; set; }

    private double _weight;
    public double Weight
    {
         get => _weight;
         set
         {
             _weight = value;

             RaisePropertyChanged();
         }
    }

    private double _sg;
    public double Sg
    {
        get => _sg;
        set
        {
            _sg = value;
            Weight = value * _volume;

            RaisePropertyChanged("Weight");
            RaisePropertyChanged("Sg");
        }
    }


    private double _volume;
    public double Volume
    {
        get => _volume;
        set
        {
            _volume = value;
            _weight = value * _sg;

            RaisePropertyChanged();
            RaisePropertyChanged("Weight");
            RaisePropertyChanged("Sg");
        }
    }
}

This is my MainVM

class MainViewModel
{
    private DataModel Data;
    public ObservableCollection<ItemViewModel> Items { get; set; }

    public ListCollectionView FilteredItems { get; set; }


    public MainViewModel()
    {
        Data = new DataModel();
        Items = new ObservableCollection<ItemViewModel>();

    FilteredItems = new ListCollectionView(Items)
    {
        Filter = item => ((ItemViewModel)item).Volume != 0,
        IsLiveFiltering = true,
        LiveFilteringProperties =
        {
            nameof (ItemViewModel.Volume)
        }
    };

        Load();
    }

    public void Load()
    {
        foreach (var item in Data.GetItems())
            Items.Add(new ItemViewModel(item.Name, item.Weight, item.Sg, item.Volume));
    }
}

I have some "DataModel"

class DataModel
{
    public List<ItemModel> GetItems() =>
        new List<ItemModel>
        {
            new ItemModel("Water", 0.00, 1.025, 0.00),
            new ItemModel("Ballast", 0.00, 1.000, 0.00),
            new ItemModel("Oil", 0.00, 1.040, 0.00),
        };
}

And this is xml i want to bind instead.

<ballast>
  <tank ID="FPTW" Name="Forepeak" Weight="0.00" SG="1.025" Volume="0.00"> </tank>
</ballast>

Please help me how can i bind this xml file instead list in DataModel.

I strongly recommend to deserialize your XML to "real" objects. In your example you want to have a list of tanks in your programm. The view (XAML) should not know if the "data storage" is a xml file, database or whatever. Just bind to a list of TankViewModel (or in your case you named it ItemViewModel . Hopefully you don't blow something up with all these tanks....

This is how you deserialize the xml to "real" objects (full working console app:

https://dotnetfiddle.net/zCHSmc

using System;
using System.IO;
using System.Xml.Serialization;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {

        MainViewModel vm = new MainViewModel();
        foreach(tank t in vm.ListOfTanks.ballast)
        {
            Console.WriteLine(t.ID);
        }


    }

    public class MainViewModel
    {
        public tanks ListOfTanks
        {
            get
            {
                string xmlContent = "<?xml version=\"1.0\" encoding=\"utf-16\"?><tanks xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">  <ballast><tank><ID>ksj</ID></tank>  </ballast></tanks>";
                tanks allTanks = null;

                XmlSerializer serializer = new XmlSerializer(typeof(tanks));

                //if you have a xml file you can use serializer.Deserialize("yourFile.xml"); instead of the "in memory stream"

                using (TextReader reader = new StringReader(xmlContent))
                {
                    allTanks =(tanks)serializer.Deserialize(reader);
                }
                return allTanks;
            }
        }
    }


    public class tanks
    {
        public tanks()
        {
            ballast = new List<tank>();
        }
        public List<tank> ballast {get;set;} 
    }


    public class tank
    {
        public string ID {get;set;}
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM