none
Darstellungsform von zwei Klassen RRS feed

  • Frage

  • Liebe User,

    ich möchte eine solche Auflistung in WPF realisieren. (Es handelt sich nur um die Mitte des Fensters! Menüpunkte, Tabs und die linke Spalte einfach außer Acht lassen)

    Ich habe zwei Klassen. K

    1. Rettungswachen (id, name)
    2. Rettungsfahrzeuge (id, rettungswachen_id, name)

    Es besteht ein direkter Bezug zwischen "id" der Rettungswachen und der "rettungswachen_id" von Rettungsfahrzeuge.

    Folgendes habe ich mir bereits gedacht:
    Eine Schleife die alle Rettungswachen durchgeht. Innerhalb der Schleife der REttungswachen läuft eine zweite Schleife die alle Fahrzeuge durchgeht und nach "rettungswachen_id" filtert. 

    Wie kann ich allerdings am besten eine solche Grafik darstellen? Die einzelnen Fahrzeuge (Im Bild: Unterhalb "RW Heide" (z.b.) werden die Fahrzeuge gelistet) sollen klickbar sein. (Bietet sich da eine Listbox mit Itemtemplate an?). 


    Mit freundlichen Grüße, Nevco

    Sonntag, 7. Februar 2016 14:58

Antworten

Alle Antworten

  • <Grid>
        <Grid Height="151" HorizontalAlignment="Left" Margin="12,28,0,0" Name="grid1" VerticalAlignment="Top" Width="147">
            <Label Content="Rettungswache 1" Height="28" HorizontalAlignment="Left" Name="label1" VerticalAlignment="Top" Width="147" Background="#FF030303" Foreground="White" FontWeight="Bold" />
            <ListView Height="117" HorizontalAlignment="Left" Margin="0,34,0,0" Name="listView1" VerticalAlignment="Top" Width="147">
                <ListViewItem Content="Fahrzeug 1" />
                <ListViewItem Content="Fahrzeug 2" />
                <ListViewItem Content="Fahrzeug 3" />
            </ListView>
        </Grid>
        <Grid Height="151" HorizontalAlignment="Left" Margin="165,28,0,0" Name="grid2" VerticalAlignment="Top" Width="147">
            <Label Background="#FF030303" Content="Rettungswache 2" FontWeight="Bold" Foreground="White" Height="28" HorizontalAlignment="Left" Name="label2" VerticalAlignment="Top" Width="147" />
            <ListView Height="117" HorizontalAlignment="Left" Margin="0,34,0,0" Name="listView2" VerticalAlignment="Top" Width="147">
                <ListViewItem Content="Fahrzeug 1" />
                <ListViewItem Content="Fahrzeug 2" />
                <ListViewItem Content="Fahrzeug 3" />
            </ListView>
        </Grid>
        <Grid Height="151" HorizontalAlignment="Left" Margin="318,28,0,0" Name="grid3" VerticalAlignment="Top" Width="147">
            <Label Background="#FF030303" Content="Rettungswache 3" FontWeight="Bold" Foreground="White" Height="28" HorizontalAlignment="Left" Name="label3" VerticalAlignment="Top" Width="147" />
            <ListView Height="117" HorizontalAlignment="Left" Margin="0,34,0,0" Name="listView3" VerticalAlignment="Top" Width="147">
                <ListViewItem Content="Fahrzeug 1" />
                <ListViewItem Content="Fahrzeug 2" />
                <ListViewItem Content="Fahrzeug 3" />
            </ListView>
        </Grid>
        <Grid Height="151" HorizontalAlignment="Left" Margin="471,28,0,0" Name="grid4" VerticalAlignment="Top" Width="147">
            <Label Background="#FF030303" Content="Rettungswache 4" FontWeight="Bold" Foreground="White" Height="28" HorizontalAlignment="Left" Name="label4" VerticalAlignment="Top" Width="147" />
            <ListView Height="117" HorizontalAlignment="Left" Margin="0,34,0,0" Name="listView4" VerticalAlignment="Top" Width="147">
                <ListViewItem Content="Fahrzeug 1" />
                <ListViewItem Content="Fahrzeug 2" />
                <ListViewItem Content="Fahrzeug 3" />
            </ListView>
        </Grid>
    </Grid>

    So stelle ich es mir vor.

    Wie kann ich nun im Code eine Grid erstellen und innerhalb der Grid ein Label und eine Listview anlegen mit entsprechenden Items?


    Mit freundlichen Grüße, Nevco

    Sonntag, 7. Februar 2016 15:34
  • Hallo Nevco,

    zunächst würde ich ein passendes ViewModel konstruieren, sodass die ganzen Elemente später bindbar sind. Im einzelnen Brauchst die eine Auflistung mit den Rettungswachen. Die darin verwendete Klasse besitzt wiederum eine Liste mit den Rettungsfahrzeugen und den Namen und der ID der Wache. Die Fahrzeug-Klasse selbst die Daten für das Fahrzeug.

    Im XAML brauchst du nun auf jeden Fall zwei Listen-Controls die sich in einander verschachteln. Das äußere bindest du an die Wachen-Liste und die innere an die jeweilige Fahrzeuge-Liste der jeweiligen Wache.

    Innerhalb des ItemTemplates der äußeren Liste platzierst du einfach einen TextBlock o.ä. für den Titel und das Listenelement für die Fahrzeuge. In dessen ItemTemplate kannst du dann u.A. Buttons verwenden. Bei denen kannst du das Click-Event abonnieren und beispielsweise über die Tag-Eigenschaft heraus finden um welches Fahrzeug es sich handelt. Besser wäre es natürlich mit Commands und deren Parametern zu arbeiten.

    Listen-Controls können beispielsweise ListBoxen oder ListViews sein. Aber theoretisch kannst du alles nutzen was von ItemsControl abgeleitet wurde.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Sonntag, 7. Februar 2016 15:42
    Moderator
  • Hi Tom, Danke für die Hilfe!

    Dies sind meine Klassen:

    private ObservableCollection<Fahrzeug> _fahrzeuge = null;
    private ObservableCollection<Wache> _wachen = null;
    
    public ObservableCollection<Fahrzeug> Fahrzeuge
    {
        get
        {
            return _fahrzeuge;
        }
        set
        {
    
            _fahrzeuge = value;
            FirePropertyChanged("Fahrzeuge");
    
        }
    }
    public ObservableCollection<Wache> Wachen
    {
        get
        {
            return _wachen;
        }
        set
        {
    
            _wachen = value;
            FirePropertyChanged("Wachen");
    
        }
    }

    Wie verschachtle ich Listen miteinander? Kannst du mir eventuell ein Beispiel anhand meiner Klassen nennen?


    Mit freundlichen Grüße, Nevco

    Sonntag, 7. Februar 2016 15:45
  • Hallo,

    hier mal ein kurzes Beispiel wie ich das meine.

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow 
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
    
    //Das sind die Datenklassen, wie sie aus der Datenbank o.ä. kommen
    public class Rettungswache
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }
    public class Rettungsfahrzeuge
    {
        public int Id { get; set; }
        public int RettungswacheId { get; set; }
        public string Name { get; set; }
    }
    
    //Basisklasse für INotifyPropertyChanged implementierende Typen
    public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
    public class MainViewModel : NotifyPropertyChangedBase
    {
        public MainViewModel()
        {
            //Pseudo-Daten generieren
            var wachen = new List<Rettungswache>();
            for (var i = 0; i < 10; ++i)
            {
                wachen.Add(new Rettungswache() { Id = i, Name = $"Rettungswache Nr. {i}"});
            }
            var rnd = new Random();
            var fahrzeuge = new List<Rettungsfahrzeuge>();
            for (var i = 0; i < 50; ++i)
            {
                fahrzeuge.Add(new Rettungsfahrzeuge() { Id = i, Name = $"Rettungswache Nr. {i}", RettungswacheId = rnd.Next(0, 10) });
            }
    
            //Wachen-Liste aus Datenbank-Listen befüllen
            foreach (var wache in wachen)
            {
                Wachen.Add(new Wache(
                    fahrzeuge.Where(x => x.RettungswacheId == wache.Id)
                                .Select(x => new Fahrzeug()
                                            {
                                                Name = $"Fahrzeug Nr. {x.Id} in Wache Nr. {wache.Id}",
                                            }))
                                {
                                    Name = wache.Name,
                                });
            }
    
        }
        public ObservableCollection<Wache> Wachen { get; } = new ObservableCollection<Wache>();
    }
    
    public class Wache : NotifyPropertyChangedBase
    {
        public Wache() : this(new ObservableCollection<Fahrzeug>()) { }
    
        public Wache(IEnumerable<Fahrzeug> fahrzeuge)
        {
            Fahrzeuge = new ObservableCollection<Fahrzeug>(fahrzeuge);
        }
    
        private string _name;
    
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name == value) return;
                _name = value;
                OnPropertyChanged();
            }
        }
    
        public ObservableCollection<Fahrzeug> Fahrzeuge { get; }
    }
    
    public class Fahrzeug : NotifyPropertyChangedBase
    {
        private string _name;
    
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name == value) return;
                _name = value;
                OnPropertyChanged();
            }
        }
    }
    <Window x:Class="WpfApplication19.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication19"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Window.DataContext>
            <local:MainViewModel/>
        </Window.DataContext>
        <Grid>
            <ItemsControl ItemsSource="{Binding Wachen}" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel>
                            <TextBlock Text="{Binding Name}"/>
                            <ItemsControl ItemsSource="{Binding Fahrzeuge}">
                                <ItemsControl.ItemTemplate>
                                    <DataTemplate>
                                        <Button Content="{Binding Name}"/>
                                    </DataTemplate>
                                </ItemsControl.ItemTemplate>
                            </ItemsControl>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Grid>
    </Window>
    

    Den Code kannst du einfach so in ein neues Projekt kopieren um zu sehen wie er funktioniert.

    Was noch fehlt ist der Click-Eventhandler für den Button bzw. der Command.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Sonntag, 7. Februar 2016 16:24
    Moderator
  • Fehler	6	Der Name "Invoke" ist im aktuellen Kontext nicht vorhanden.	
    Fehler	3	Der Typ- oder Namespacename "CallerMemberName" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)	
    Fehler	4	Der Typ- oder Namespacename "CallerMemberNameAttribute" konnte nicht gefunden werden. (Fehlt eine Using-Direktive oder ein Assemblyverweis?)
    Fehler	5	Nur assignment-, call-, increment-, decrement- und "new object"-Ausdrücke können als Anweisung verwendet werden.
    Fehler	11	Syntaxfehler. ":" erwartet.	
    Fehler	10	Ungültiger Ausdruck ".".	
    Fehler	2	Ungültiges Token "(" in Klasse, Struktur oder Schnittstellenmemberdeklaration.	
    Fehler	1	Ungültiges Token "=" in Klasse, Struktur oder Schnittstellenmemberdeklaration.	
    


    Mit freundlichen Grüße, Nevco

    Freitag, 12. Februar 2016 18:19
  • Hallo,

    ich rate mal und sage die Fehlerliste bezieht sich auf meinen Code?

    Die fehlenden Namespaces kannst du ganz einfach in der MSDN finden.

    using System.Runtime.CompilerServices;
    Die anderen Fehler kann ich mir nur erklären wenn du kein C# 6 nutzt. In dem Fall musst du noch die neueren Features übersetzen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Samstag, 13. Februar 2016 00:31
    Moderator
  • Wie finde ich raus, welches C# ich nutze?Die Namespaces haben nichts gebracht.


    Mit freundlichen Grüße, Nevco

    Samstag, 13. Februar 2016 22:20
  • Hallo,

    die C#-Version findest du unter dem Erweitert Button im Build-Tab der Projekteigenschaften bzw. in den Eigenschaften der Projektmappe. Wenn CallerMemberName nicht gefunden wird, verwendest du .NET 4.0 oder älter. Ich habe dir nochmal den ganzen Code in die alte Version übersetzt:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    
    namespace WpfApplication19
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow
        {
            public MainWindow()
            {
                this.InitializeComponent();
            }
        }
    
        //Das sind die Datenklassen, wie sie aus der Datenbank o.ä. kommen
        public class Rettungswache
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class Rettungsfahrzeuge
        {
            public int Id { get; set; }
            public int RettungswacheId { get; set; }
            public string Name { get; set; }
        }
    
        //Basisklasse für INotifyPropertyChanged implementierende Typen
        public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                var onPropertyChanged = this.PropertyChanged;
                if (onPropertyChanged != null) onPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public class MainViewModel : NotifyPropertyChangedBase
        {
            public MainViewModel()
            {
                this.Wachen = new ObservableCollection<Wache>();
    
                //Pseudo-Daten generieren
                var wachen = new List<Rettungswache>();
                for (var i = 0; i < 10; ++i)
                {
                    wachen.Add(new Rettungswache() { Id = i, Name = string.Format("Rettungswache Nr. {0}", i) });
                }
                var rnd = new Random();
                var fahrzeuge = new List<Rettungsfahrzeuge>();
                for (var i = 0; i < 50; ++i)
                {
                    fahrzeuge.Add(new Rettungsfahrzeuge() { Id = i, Name = string.Format("Rettungswache Nr. {0}", i), RettungswacheId = rnd.Next(0, 10) });
                }
    
                //Wachen-Liste aus Datenbank-Listen befüllen
                foreach (var wache in wachen)
                {
                    this.Wachen.Add(new Wache(
                        fahrzeuge.Where(x => x.RettungswacheId == wache.Id)
                                    .Select(x => new Fahrzeug()
                                    {
                                        Name = string.Format("Fahrzeug Nr. {0} in Wache Nr. {1}", x.Id, wache.Id),
                                    }))
                    {
                        Name = wache.Name,
                    });
                }
            }
            public ObservableCollection<Wache> Wachen { get; private set; }
        }
    
        public class Wache : NotifyPropertyChangedBase
        {
            public Wache() : this(new ObservableCollection<Fahrzeug>()) { }
    
            public Wache(IEnumerable<Fahrzeug> fahrzeuge)
            {
                this.Fahrzeuge = new ObservableCollection<Fahrzeug>(fahrzeuge);
            }
    
            private string _name;
    
            public string Name
            {
                get { return this._name; }
                set
                {
                    if (this._name == value) return;
                    this._name = value;
                    this.OnPropertyChanged("Name");
                }
            }
    
            public ObservableCollection<Fahrzeug> Fahrzeuge { get; private set; }
        }
    
        public class Fahrzeug : NotifyPropertyChangedBase
        {
            private string _name;
    
            public string Name
            {
                get { return this._name; }
                set
                {
                    if (this._name == value) return;
                    this._name = value;
                    this.OnPropertyChanged("Name");
                }
            }
        }
    }
    


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Samstag, 13. Februar 2016 23:24
    Moderator
  • Hallo Tom, das schaut bisher schon ziemlich gut aus bei mir!

    Irgendwas stimmt allerdings mit den Strings noch nicht, denke ich, oder?


    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 16:55
  • Hallo Nevco,

    es sieht so aus als ob die Name-Eigenschaften (von beiden Klassen) entweder alle leer sind oder aber etwas mit dem Binding nicht klappt.

    Hast du 1 zu 1 meinen Code genommen? Steht in der Ausgabe, wärend der Ausführung des Programms, irgend etwas über ein nicht funktionierendes Binding?


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Mittwoch, 17. Februar 2016 17:00
    Moderator
  • Ja, allerdings kann ich damit nichts anfangen.
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=64707242)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=64707242); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=2925703)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=2925703); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=52844977)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=52844977); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=19160433)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=19160433); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=47380263)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=47380263); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=63542621)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=63542621); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=55110660)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=55110660); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=44944564)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=44944564); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=30787823)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=30787823); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=54341214)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=54341214); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=13397265)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=13397265); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=29794011)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=29794011); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=13594899)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=13594899); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=20519973)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=20519973); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=36012562)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=36012562); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=120067)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=120067); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=4922760)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=4922760); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=506587)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=506587); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=20770076)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=20770076); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=46266773)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=46266773); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=17889527)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=17889527); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=15630920)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=15630920); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=36887967)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=36887967); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=36011668)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=36011668); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=83399)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=83399); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=3419394)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=3419394); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=5977462)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=5977462); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=27297325)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=27297325); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=45448534)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=45448534); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=51450605)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=51450605); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=29100051)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=29100051); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=37180985)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=37180985); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=48025404)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=48025404); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=22884531)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=22884531); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=65850542)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=65850542); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=15517670)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=15517670); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=46676368)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=46676368); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=34682922)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=34682922); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=12713695)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=12713695); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=40244104)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=40244104); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=39395563)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=39395563); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=4605357)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=4605357); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=54601919)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=54601919); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=24086204)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=24086204); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=47081572)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=47081572); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=51296274)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=51296274); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=22772454)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=22772454); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=61255402)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=61255402); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=28443535)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=28443535); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=25334253)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=25334253); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=63366251)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=63366251); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=47879483)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=47879483); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=16901761)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=16901761); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=21883591)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=21883591); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=24812030)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=24812030); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Wache' (HashCode=10660286)'. BindingExpression:Path=Name; DataItem='Wache' (HashCode=10660286); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=54474770)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=54474770); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=18873092)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=18873092); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=35599293)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=35599293); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' ''Fahrzeug' (HashCode=50284869)'. BindingExpression:Path=Name; DataItem='Fahrzeug' (HashCode=50284869); target element is 'Button' (Name=''); target property is 'Content' (type 'Object')
    


    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 17:13
  • Mein Code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.ComponentModel;
    using System.Collections.ObjectModel;
    using System.Runtime.CompilerServices;
    namespace taheri_sim
    {
        /// <summary>
        /// Interaktionslogik für WindowEinsatzmittel.xaml
        /// </summary>
        public partial class WindowEinsatzmittel 
        {
            public WindowEinsatzmittel()
            {
                InitializeComponent();
            }
        }
        //Das sind die Datenklassen, wie sie aus der Datenbank o.ä. kommen
        public class Rettungswache
        {
            public int Id { get; set; }
            public string Name { get; set; }
        }
        public class Rettungsfahrzeuge
        {
            public int Id { get; set; }
            public int RettungswacheId { get; set; }
            public string Name { get; set; }
        }
    
        //Basisklasse für INotifyPropertyChanged implementierende Typen
        public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            protected virtual void OnPropertyChanged(string propertyName)
            {
                var onPropertyChanged = this.PropertyChanged;
                if (onPropertyChanged != null) onPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public class MainViewModel : NotifyPropertyChangedBase
        {
            public MainViewModel()
            {
                this.Wachen = new ObservableCollection<Wache>();
    
                //Pseudo-Daten generieren
                var wachen = new List<Rettungswache>();
                for (var i = 0; i < 10; ++i)
                {
                    wachen.Add(new Rettungswache() { Id = i, Name = string.Format("Rettungswache Nr. {0}", i) });
                }
                var rnd = new Random();
                var fahrzeuge = new List<Rettungsfahrzeuge>();
                for (var i = 0; i < 50; ++i)
                {
                    fahrzeuge.Add(new Rettungsfahrzeuge() { Id = i, Name = string.Format("Rettungsfahrzeug Nr. {0}", i), RettungswacheId = rnd.Next(0, 10) });
                }
    
                //Wachen-Liste aus Datenbank-Listen befüllen
                foreach (var wache in wachen)
                {
                    this.Wachen.Add(new Wache(
                        fahrzeuge.Where(x => x.RettungswacheId == wache.Id)
                                    .Select(x => new Fahrzeug()
                                    {
                                        name = string.Format("Fahrzeug Nr. {0} in Wache Nr. {1}", x.Name, wache.Id),
                                    }))
                    {
                        name = wache.Name,
                    });
                }
            }
            public ObservableCollection<Wache> Wachen { get; private set; }
        }
    
    }
    


    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 17:13
  • Die Fehlermeldung sagt eindeutig, dass die Eigenschaft "Name" in "Wache" bzw. "Fahrzeug" nicht gefunden wird. Nun kenne ich die beiden Klassen nicht, in deinem gezeigten Code weist du aber "name" (klein geschrieben") zu. Bei Bindungen wird allerdings die Groß- und Kleinschreibung beachtet.

    In meinem originalen Code wird "Name" groß geschrieben (so wie es nach der C# Konvention auch sein sollte). Bei dir wird er wohl klein geschrieben sein weshalb du die Fehlermeldungen bekommst.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets


    Mittwoch, 17. Februar 2016 17:27
    Moderator
  • Ich Vollidiot. Hab den Fehler - hab die Bindings im Code geändert, aber nicht im xaml.

    Danke für deine Hilfe, es funktioniert!


    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 17:36
  • Jetzt möchte ich aber deine Pseudo-Datensätze "weghaben" und dafür meine vorhandenen Collections "Data.Source.Fahrzeug" und "Data.Source.Wache" verwenden. Wie kann ich das umsetzen?

    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 17:42
  • Ganz um die 2 zusätzlichen Klassen wirst du nicht drum herum kommen. Im XAML brauchst du eine Hierarchische Struktur der Daten, die deine Klassen zwar logisch haben, aber der Zugriff geht nicht entsprechend.

    Möglich wäre noch, dass du alle Wachen einfach so an die UI gibst und dann per Converter die passenden Fahrzeuge als Sub-Liste heraus holst um die innere ListView zu befüllen.

    Sofern du in den Datenklassen INotifyPropertyChanged implementierst geht sollte das auch Problemlos gehen. Aus Sicht des Nicht-Datenbank-Entwicklers sehe ich die 2 zusätzlichen Klassen jedoch als am elegantesten an.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Mittwoch, 17. Februar 2016 17:55
    Moderator
  • Danke für die Antwort.

    Eine Frage, wieso funktioniert es nicht auf diesem Weg?

        public class MainViewModel : NotifyPropertyChangedBase
        {
            public MainViewModel()
            {
                var wachen = Data.Source.Wachen;
                var rnd = new Random();
                var fahrzeuge = Data.Source.Fahrzeuge;
    
                foreach (var wache in Data.Source.Wachen)
                {
                    MessageBox.Show(wache.name + " - DEBUG");
                    Data.Source.Wachen.Add(new Wache(
                        Data.Source.Fahrzeuge.Where(x => x.f_wachid == wache.id)
                                    .Select(x => new Fahrzeug()
                                    {
                                        name = string.Format("{0} {1} {2}/{3}/{4}", x.name, wache.kuerzel, x.f_wache, x.f_kennung, x.f_nummer),
                                    }))
                    {
                        name = wache.name,
                    });
                }
            }
            public ObservableCollection<Wache> Wachen { get; private set; }
        }


    Mit freundlichen Grüße, Nevco

    Mittwoch, 17. Februar 2016 18:26
  • Hallo Nevco,

    was funktioniert hier nicht? Das einzige was ich hier sehe ist, dass du die erstellten Instanzen von "Wache" versuchst zu Data.Source.Wachen anstatt zu Wachen hinzuzufügen. Das sollte die Fehlermeldung, die du in dem Fall bekommst, aber auch eindeutig zeigen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Donnerstag, 18. Februar 2016 01:07
    Moderator
  • Habe meinen Code nun entsprechend angepasst, dass es passt.

    Folgende Frage: Wie kann ich nun umsetzen, dass die Stackpanels horizontal angereiht werden und maximal 6 nebeneinander gereiht werden? Ab 6 nebeneinander wird in der nächsten Zeile mit 6 weiteren weitergemacht. (siehe Bild ganz oben)


    Mit freundlichen Grüße, Nevco

    Donnerstag, 18. Februar 2016 12:29
  • Hallo,

    mit dem StackPanel geht das nicht, jedoch mit einem WrapPanel. Dieses kannst du als ItemsPanelTemplate der ListBox zuweisen, dann wird entsprechend in neue Zeilen umgebrochen. Die Anzahl der Items auf einer Zeile ist abhängig von deren Breite.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Donnerstag, 18. Februar 2016 17:41
    Moderator
  • Verstanden und erfolgreich umgesetzt.

    (Hoffentlich) letzte Frage meinerseits: Wie kann ich nun von einem angeklickten Button die x.id übergeben? 


    Mit freundlichen Grüße, Nevco

    Donnerstag, 18. Februar 2016 19:40
  • Wenn du mit Commands arbeitest, dann kannst du CommandParameter an x bzw. x.id binden. In der mit dem Command verknüpften Methode erhältst du dann den Parameter.

    Wenn du dagegen mit dem Click-Event arbeitest, steht dir dafür die Tag-Eigenschaft zur Verfügung. Den Auslösenden Button erhältst du im Clic-Event als sender, von diesem kannst du Tag dann wieder auslesen.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    • Als Antwort markiert Nevco Freitag, 19. Februar 2016 13:29
    Donnerstag, 18. Februar 2016 19:52
    Moderator
  • Dankeschön. Hier der Code, falls die Frage bei anderen nochmal auftreten sollte:

    Button b = (Button)sender;
    MessageBox.Show("ID: " + b.Tag);


    Mit freundlichen Grüße, Nevco

    Donnerstag, 18. Februar 2016 20:26
  • Wenn ich nun aber Werte in der Collection verändere, werden die Button-Contents nicht aktualisiert, obwohl es sich um eine ObservableCollection handelt. Woran kann das liegen?

    Danke!


    Mit freundlichen Grüße, Nevco

    Freitag, 19. Februar 2016 13:49
  • Was haben die Button-Contents mit den Collections zu tun? Wenn du ein Element zur Collection hinzufügst müsste ein neuer Button auftauchen. Das die UI über die Änderung de Liste informiert wird, dafür sorgt die INotifyCollectionChanged-Schnittstelle, die von der ObservableCollection<T>-Klasse implementiert wird.

    Wenn sich dagegen eine Eigenschaft ändert, muss im Setter das PropertyChanged-Event der INotifyPropertyChanged-Schnittstelle ausgelöst werden. Um das nicht jedes mal alles implementieren zu müssen habe ich in meinem Beispiel dafür die gemeinsame Basisklasse NotifyPropertyChangedBase erstellt.


    Tom Lambert - .NET (C#) MVP
    Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
    Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
    Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets

    Freitag, 19. Februar 2016 14:15
    Moderator