Laden...

DelegateCommand/Event eines Objects in einer ObservableCollection

Erstellt von manullino vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.208 Views
manullino Themenstarter:in
371 Beiträge seit 2008
vor 14 Jahren
DelegateCommand/Event eines Objects in einer ObservableCollection

Hallo @all,

zur Steuerung unserer Modelleisenbahn schreibe ich gerade eine neue Anwendung in WPF.

Nun habe ich ein kleines Problem:

Fuer jede Lokomotiven gibts ein Object:

public class Loco : INotifyPropertyChanged 
    {
        public Guid Guid { get; set; }
        public string Type { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
        public string Protocol { get; set; }
         int speedLevel;
        public int SpeedLevel
        {
            get { return speedLevel; }
            set 
            { 
                speedLevel = value;
                NotifyPropertyChanged("SpeedLevel");
            }
        } 
}

Auf meiner WPF Form habe ich eine ObservableCollection<Loco>.

            AllLoco = new ObservableCollection<Loco>();
            AllLoco = Database.GetLoco();

Diese ObservableCollection habe ich an eine Listbox gebunden. Die Listbox habe ich so geandert, dass man fuer jede Lokomotive die Geschwindigkeit einstellen kann.
(siehe Anhang)

Wie kann ich den nun ein DelegateCommand ausfuheren, wenn sich die Geschwindigkeit (Seedlevel) aendert? Theoretische muesse, das DG auf dem Object liegen und dann auf das ViewModell verweisen, oder? Koennte man das auch ueber einen Event loesen?

Wie stelle ich es also am besten an, dass ich von dem Object (in der ObservableCollection) auf das ViewModel verweisen bzw. eine Methode des ViewModels aufrufen kann?

Danke,
Manullino

U
1.578 Beiträge seit 2009
vor 14 Jahren

das loco objekt kennt das viewmodel auch nicht
waere ja auch schlimnm zwecks weiterverwendung
es ist eher anders herum

das loco objekt schickt ein event und das viewmodel aboniert das beim hinzufuegen in die liste
da du aber bereits das PropertyChanged hast kannst du das nehmen

hier mal pseudo


public class Loco : INotifyPropertyChanged
{
    int speedLevel;
    public int SpeedLevel
    {
        get { return speedLevel; }
        set
        {
            speedLevel = value;
            NotifyPropertyChanged("SpeedLevel");
    
        }
    }
}

public Bla()
{
    //AllLoco = new ObservableCollection<Loco>();
    //eine zuweisung macht das new von vorher obsolet
    AllLoco = Database.GetLoco();
    foreach (var loco in AllLoco)
        loco.PropertyChanged += (sender, e) =>
        {
            if (e.PropertyName.Equals("SpeedLevel")
                DoSomethingIfSpeedLevelChanged(sender as Loco);
        };
}

andere anmerkung
das "Loco" sollte "LocoViewModel" heissen, evtl auch ein richtiges "Loco" ohne das notify kapseln

public class Loco
{
    public Guid Guid { get; set; }
    public string Type { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Protocol { get; set; }
    public int SpeedLevel { get; set; }
}

public class LocoViewModel : ViewModelBase
{
    public Loco Model { get; private set; }

    public LocoViewModel(Loco model)
    {
        Model = model;
    }

    public Guid Guid
    {
        get { return Model.Guid; }
        set
        {
            Model.Guid = value;
            OnPropertyChanged(this, "Guid");
        }
    }
    ...
    ...
    ...
}
143 Beiträge seit 2008
vor 14 Jahren

Hi,

winSharp93 hat mir mal den Namen ModelViewModel für ViewModels, welche ein Model wrapen, vorgeschlagen. Seit dem verwende ich diesen Namen. Ist nach meiner Meinung eine sehr sinnvolle Sache.

Gruß Timo

manullino Themenstarter:in
371 Beiträge seit 2008
vor 14 Jahren

So, habe nun endlich ein ModelViewModel um das Model gebaut, wie ihr es mir geraten habt. Nun weiss ich allerdings nicht, wie ich das Model / bzw. alle Models in der ObservableCollection<ModelViewModel> serialisieren kann.

Bisher hatte ich es so:

    public static void SaveLocos(ObservableCollection<LocoViewModel> locos)
        {
            XmlSerializer ser = new XmlSerializer(typeof(ObservableCollection<LocoViewModel>));
            if (File.Exists(LogoFile))
            {
                File.Delete(LogoFile);
            }

            try
            {
                using (FileStream str = new FileStream(LogoFile, FileMode.CreateNew, FileAccess.ReadWrite))
                {
                    ser.Serialize(str, locos);
                    str.Close();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(String.Format("Fehler beim Speichern. \n{0}", ex.Message));
            }

        }
U
1.578 Beiträge seit 2009
vor 14 Jahren

ist diese methode in model oder im viewmodel ?
denn eine ObservableCollection gehoert nicht ins model

das speichern sollte normalerweise im model sein, und das model nimmt dann eine Liste von den objekten an
also


// Model
public static void SaveLocos(IEnumerable<Loco> locos)
{
    ...
}

im viewmodel kannst du das dann einfach realisieren


// ViewModel
public void SaveLocos() // vom SaveLocosCommand
{
    // ausgehend davon das eine ObservableCollection<LocoViewModel> Locos existiert
    Model.SaveLocos(Locos.Select(l => l.Model));
}

das folgt dem prinzip das die ViewModel nur ein vermittler ist zwischen die liste in den models und eine bindbare liste fuer die ui

zu deinem serializing problem kann ich nichts sagen - hab das so noch nie benutzt