Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

1

09.07.2013, 17:09

[Wpf] TreeView lässt nur SupItems beim ersten Knoten zu

Hallo Community,

ja schon wieder eine Frage in recht kurzer Zeit, leider kann mir Google bei dieser Fragestellung nicht wirklich eine Lösung mit Google finden...

Ich habe ein TreeView und möchte dort an einem meiner 10 Knoten, je nach aktuell Selektiertem Item, ein SupItem hinzufügen.
Dies klappt leider nur, wenn "Kategorie1" markiert ist, bei allen anderen sehe ich nur meine Test-Meldung.

Woran könnte das liegen?

Hier mal mein Code:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
 public partial class Auswahlfenster : Window
    {        public TreeViewItem Kategorie1;
        public TreeViewItem Kategorie2;
        public TreeViewItem Kategorie3;
        public TreeViewItem Kategorie4;
        public TreeViewItem Kategorie5;
        public TreeViewItem Kategorie6;
        public TreeViewItem Kategorie7;
        public TreeViewItem Kategorie8;
        public TreeViewItem Kategorie9;
        public TreeViewItem Kategorie10;

        public Auswahlfenster()        { InitializeComponent();


            Kategorie1 = new TreeViewItem() { Header = "Kategorie1" };
            Kategorie2 = new TreeViewItem() { Header = "Kategorie2" };
            Kategorie3 = new TreeViewItem() { Header = "Kategorie3" };
            Kategorie4 = new TreeViewItem() { Header = "Kategorie4" };
            Kategorie5 = new TreeViewItem() { Header = "Kategorie5" };
            Kategorie6 = new TreeViewItem() { Header = "Kategorie6" };
            Kategorie7 = new TreeViewItem() { Header = "Kategorie7" };
            Kategorie8 = new TreeViewItem() { Header = "Kategorie8" };
            Kategorie9 = new TreeViewItem() { Header = "Kategorie9" };
            Kategorie10 = new TreeViewItem() { Header = "Kategorie10" };
            treeView1.Items.Add(Kategorie1);
            treeView1.Items.Add(Kategorie2);
            treeView1.Items.Add(Kategorie3);
            treeView1.Items.Add(Kategorie4);
            treeView1.Items.Add(Kategorie5);
            treeView1.Items.Add(Kategorie6);
            treeView1.Items.Add(Kategorie7);
            treeView1.Items.Add(Kategorie8);
            treeView1.Items.Add(Kategorie9);
            treeView1.Items.Add(Kategorie10);

        }

        private void treeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)        {
            TreeViewItem item = treeView1.SelectedItem as TreeViewItem;
            textBox2.Text = item.Header.ToString();

        }


        private void textBox2_TextChanged(object sender, TextChangedEventArgs e)        {

            if (textBox2.Text != "")
            {                TreeViewItem item = treeView1.SelectedItem as TreeViewItem;
                item.Header = textBox2.Text;            }        }


        private void bEntfernen_Click(object sender, RoutedEventArgs e)        {
        }
        private void bHinzufuegen_Click(object sender, RoutedEventArgs e)        {
            TreeViewItem item = new TreeViewItem();
            item.Header = "BitteTitelEingeben";

            if (Kategorie1.IsSelected){                Kategorie1.Items.Add(item);      MessageBox.Show("1");}

            else if (Kategorie2.IsSelected)            {                Kategorie2.Items.Add(item);     MessageBox.Show("2");}

            else if (Kategorie3.IsSelected)            {                Kategorie3.Items.Add(item);     MessageBox.Show("3");}

            else if (Kategorie4.IsSelected)            {                Kategorie4.Items.Add(item);     MessageBox.Show("4");}

            else if (Kategorie5.IsSelected)            {                Kategorie5.Items.Add(item);     MessageBox.Show("5");}

            else if (Kategorie6.IsSelected)            {                Kategorie6.Items.Add(item);     MessageBox.Show("6");}

            else if (Kategorie7.IsSelected)            {                Kategorie7.Items.Add(item);     MessageBox.Show("7");}

            else if (Kategorie8.IsSelected)            {                Kategorie8.Items.Add(item);     MessageBox.Show("8");}

            else if (Kategorie9.IsSelected)            {                Kategorie9.Items.Add(item);     MessageBox.Show("9");}

            else if (Kategorie10.IsSelected)            {                Kategorie10.Items.Add(item);       MessageBox.Show("10");}

        }    }



Danke schon mal für eure Hilfe.
Gruß,
MitgliedXYZ

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

09.07.2013, 18:27

Ich kann dir bei deinem derzeitigen Problem nicht helfen, aber ich kann sagen:
nimm deinen bisherigen Code, schmeiß ihn weg und mach es unter Verwendung von WPF (und XAML) nochmal!

Die ganzen Elemente, die du per Code hinzufügst, sollten nicht per Code hinzugefügt werden. Auch wenn die Elemente dynamisch sind, kannst du das mit WPF-Mitteln lösen, siehe ContentTemplate.

Vielleicht solltest du dir auch einfach über den Tree das ausgewählte Element holen und darauf deine gewünschten Aktionen ausführen. Dadurch sparst du dir dieses Konstrukt von Bedingungen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

09.07.2013, 18:36

Suche mal wie man treeviews i wpf über xaml erstellt. Wenn du eine feste anzahl an elementen hast ist das ok. Ansonsten such mal nach wpf treeview hierarchical datatemplate. ; )

MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

4

09.07.2013, 19:48

Suche mal wie man treeviews i wpf über xaml erstellt. Wenn du eine feste anzahl an elementen hast ist das ok. Ansonsten such mal nach wpf treeview hierarchical datatemplate. ; )
Feste Anzahl habe ich nicht ganz. Nur die 10 Überkategorien stehen fest. Diese sollen aber zur Laufzeit dynamisch viele Items bekommen.

Hab folgendes Tutorial gefunden, dass werde ich jetzt mal versuchen an mein Programm anzupassen:
http://blogs.msdn.com/b/mikehillberg/arc…ep-by-step.aspx

Edit:
Für dem unten geposteten Codeausschnitt fehlen in diesem Tutorial die Klassen "Team", "Conference", etc. Sollte das nur ein Beispiel sein und man muss sich die Klassen selbst schreiben? Sonst würde sich dieses Tutorial in der online Version ja gar nicht ausführen lassen...

var western = new Conference("Western")
{
Teams =
{
new Team("Club Deportivo Chivas USA"),
new Team("Colorado Rapids"),
new Team("FC Dallas"),
new Team("Houston Dynamo"),
new Team("Los Angeles Galaxy"),
new Team("Real Salt Lake"),
new Team("San Jose Earthquakes"),
new Team("Seattle Sounders FC"),
new Team("Portland 2011"),
new Team("Vancouver 2011")
}
};
var eastern = new Conference("Eastern")
{
Teams =
{
new Team("Chicago Fire"),
new Team("Columbus Crew"),
new Team("D.C. United"),
new Team("Kansas City Wizards"),
new Team("New York Red Bulls"),
new Team("New England Revolution"),
new Team("Toronto FC"),
new Team("Philadelphia Union 2010")
}
};
var league = new Collection<Conference>() { western, eastern };
DataContext = new
{
WesternConference = western,
EasternConference = eastern,
League = league
};



Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »MitgliedXYZ« (09.07.2013, 20:00)


Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

5

10.07.2013, 00:05

Sich die Klassen dafür zu erstellen dürfte ja nicht besonders schwer sein:
Team besitzt den String Name (o. ä.) und eine List<String> für Players (letzteres war eher im XAML-Code ersichtlich)
Conference besitzt einen String Name und eine List<Team> für Teams
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

6

10.07.2013, 09:03

Die Idee ist, dass du Datenklassen implementierst, die genau deine Struktur abbilden. Danach musst du nur anfangen und entsprechend die Wpf-Oberfläche bauen. ICh zeige dir ein etwas vereinfachtes Beispiel:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler OnPropertyChanged;
    
    protected void OnPropertyChanged(string propertyName)
    {
        if (OnPropertyChanged != null) OnPropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

class SubItemViewModel : ViewModel
{
    private string _name;

    public string Name 
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }
}

class MainWindowViewModel : ViewModel
{
    public MainWindowViewModel()
    {
        Items = new ObservableCollection<CategoryViewModel>();
    }

    public ObservableCollection<CategoryViewModel> Items { get; private set;}
}

class CategoryViewModel : ViewModel
{
    private string _name;
    
    public Category()
    {
        Items = new ObservableCollection<SubItemViewModel>();
    }

    public string Name 
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }
    
    public ObservableCollection<SubItemViewModel> Items { get; private set;}
}
    public string Name 
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }
}

class Category : ViewModel
{
    private string _name;
    
    public Category()
    {
        Items = new ObservableCollection<SubItem>();
    }

    public string Name 
    {
        get { return _name; }
        set 
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }
    
    public ObservableCollection<SubItem> Items { get; private set;}
}


Dazu entsprechend der MainWindow.xaml.cs:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
public MainWindow()
{
    InitializeComponent();
    
    var mainWindowViewModel= new MainWindowViewModel();
    mainWindowViewModel.Items.Add(new CategoryViewModel { Name = "Category1" });
    mainWindowViewModel.Items.Add(new CategoryViewModel { Name = "Category2" });
        mainWindowViewModel.Items[0].Items.Add(new SubItemViewModel { "SubItem1" });
        mainWindowViewModel.Items[0].Items.Add(new SubItemViewModel { "SubItem2" });
        mainWindowViewModel.Items[1].Items.Add(new SubItemViewModel { "SubItem1" });
    
    DataContext = mainWindowViewModel;
}


Und der Xaml-Code für das MainWindow:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<Window x:Class="TestProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="Test" 
        Height="480" 
        Width="640">
    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type CategoryViewModel}" ItemsSource="{Binding Items}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate DataType="{x:Type SubItemViewModel}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
    </Window.Resources>
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="300" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        
        <TreeView ItemsSource="{Binding Items}" />
    </Grid>
</Window>


Danach musst du nurnoch mit dem ViewModels arbeiten den Rest macht WPF automatisch ;)

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »TrommlBomml« (11.07.2013, 08:47)


MitgliedXYZ

Alter Hase

  • »MitgliedXYZ« ist der Autor dieses Themas

Beiträge: 1 369

Wohnort: Bayern

  • Private Nachricht senden

7

10.07.2013, 20:18

Danke TrommlBomml für dein Beispiel, hat mir wirklich geholfen. :thumbup:
Ich hab mein Programm nun nach diesem Vorbild angepasst, wenn man es so benutzt bietet Wpf wirklich Vorteile...
Der Einstieg fällt nur etwas schwerer, als bei WindowsForms, aber ich werde wohl nicht mehr auf diese zurückgreifen, schon alleine weil Wpf auch mehr Optionen zur UI Gestaltung bietet.

Schönen Gruß,
MitgliedXYZ

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

8

11.07.2013, 08:47

Da ist übrigens noch ein kleiner Fehler im MainWindow.xaml.cs (DataContext war falsch gesetzt). Dann frohes Schaffen! ;)

Werbeanzeige