Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
[erledigt] WPF MVVM : TreeView
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

[erledigt] WPF MVVM : TreeView

beantworten | zitieren | melden

Hallo zusammen,
nun muss ich auch mal mit neuem GUI zeugs arbeiten ;-)

Ich will einen TreeView darstellen.

<TreeView ItemsSource="{Binding Items}">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" > 
                    <Style.Triggers>
                        <Trigger Property="HasItems" Value="true">
                            <Setter Property="Focusable" Value="False"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
                <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding SubNodes}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <CheckBox Grid.Column="0"/>
                        <TextBlock Text="{Binding Text}" Grid.Column="1"/>
                    </Grid>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>

Das klappt auch alles wunderbar nur :
Frage 1-> Wie kann ich zB den Items ein anderes template zuweisen ? (Also Items sollen keine Checkbox haben , die SubNodes aber schon)
Frage 2-> Ich wil lzwei Darstellungsformen : Einmal SubNodes MIT Checkbox und einmal ohne. Bisher habe ich durch Googlen nicht rausgefunden, wie ich zB zwei Templates dem Grid zuweisen kann

Frage 3. -> Wenn ein SubNode mit Checkbox angehakt wurde, sollen alle anderen SubItems Disabled werden. Bestimmt über Trigger nur wie ist mir gerade rätselhaft.

Kann mir jmd helfen ?

Grüße
Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von Ahrimaan am .
private Nachricht | Beiträge des Benutzers
xxMUROxx
myCSharp.de - Member

Avatar #avatar-3236.jpg


Dabei seit:
Beiträge: 1626
Herkunft: Südtirol/Italien

beantworten | zitieren | melden

Hallo Ahrimaan,

hab zwar nie was mit TreeView gemacht, aber ich versuchs mal

Du hast sicherlich im ViewModel auch eine Tree-Structure. Dann lässt sich sicherlich herausfinden ob das Item ein, LeavType oder eben ein RootType ist. Dementsprechend wäre die ComboBox anzuzeigen oder zu verstecken.

Wie ich sehe hast du etwas ähnliches im Trigger schon gemacht..
Wenn HasItems=true, dann ist es ein RootType sonst ein LeaveType.

Gruß
Michael
Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi,
ja ich kann den Trigger ansprechen und trotzdem weiß ich immer noch nicht wie ich dann eine Combobox einblende oder ausblende .....

Zu den anderen Fragen hast du nicht auch zufällig ne Antwort ? :-)

Grüße
private Nachricht | Beiträge des Benutzers
wackelkontakt
myCSharp.de - Member

Avatar #avatar-3290.jpg


Dabei seit:
Beiträge: 109
Herkunft: Dresden

beantworten | zitieren | melden

Hallo Ahrimaan,

mit dem TreeView habe ich auch noch nicht gearbeitet aber verschiedene Templates einem Grid zuweisen kannst du über DataGridTemplateColumn erreichen. Hier mal ein abgekürztes Beispiel von mir mit einem Template in der ersten Spalte und Text in der zweiten Spalte (ich hoffe mal das das auch dein Problem ist, ist nämlich für mich nicht so ganz ersichtlich)

        <DataGrid>
            <DataGrid.Columns>
                <DataGridTemplateColumn Width="Auto">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Image Height="20" Source="{Binding Image}"/>
                            </StackPanel>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTextColumn
    				Width="*"
    				Binding="{Binding Message}" 
    				CanUserSort="False">
                    <DataGridTextColumn.Header>
                        <Label FontWeight="Bold" 
                               Background="#00350E0E" 
                               Content="Message" 
                               HorizontalContentAlignment="Center"/>
                    </DataGridTextColumn.Header>
                    <DataGridTextColumn.ElementStyle>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="TextWrapping" Value="Wrap"/>
                            <Setter Property="TextAlignment" Value="Justify"/>
                            <Setter Property="Background" Value="{Binding Background}"/>
                        </Style>
                    </DataGridTextColumn.ElementStyle>
                </DataGridTextColumn>
            </DataGrid.Columns>
        </DataGrid>

Edit: zu deiner ersten Frage: Wie gesagt kenne ich den WPF-Treeview und seine Möglichkeiten nicht aber dies läßt sich sicherlich über den DataTemplateSelector lösen. Wobei ich denke das diese Lösung ziemlich unperformant ist... aber wenn du keine andere Lösung findest könntest du es damit probieren.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von wackelkontakt am .
Um Rekursion zu verstehen, muss man erst mal Rekursion verstehen, muss man erst mal Rekursion verstehen, ....
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hi,
danke für eure Tipps :
Ich habe es nun probiert anders zu lösen :

Ich will nun für gewisse Typen ein anderes aussehen machen.
Mir werden zwar nun die Rootnodes angezeigt aber nicht mehr die Subnodes.
Ich haben den Binding path auf SubNodes gesetzt.
Sicher übersehe ich was oder ?
<TreeView ItemsSource="{Binding Items}" Grid.Row="0">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" > 
                    <Style.Triggers>
                        <Trigger Property="HasItems" Value="true">
                            <Setter Property="Focusable" Value="False"/>
                        </Trigger>
                        <Trigger Property="IsSelected" Value="true">
                            
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type Model:RootNode}">
                    <TextBlock Text="{Binding Text}"/>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type Model:SubNode}" ItemsSource="{Binding Path=SubNodes}">
                    <TextBlock Text="{Binding Text}"/>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
         </TreeView>

Grüße
private Nachricht | Beiträge des Benutzers
Ahrimaan
myCSharp.de - Member



Dabei seit:
Beiträge: 363
Herkunft: Thorn

Themenstarter:

beantworten | zitieren | melden

Hallo,
hier die Antwort :

Ich erstelle ein Interface INode

Davon leite ich zwei Klassen ab : SubNode und SubNodewithCheckbox
<Window x:Class="MK.AgentWpf.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:MK.AgentWpf.ViewModel"
        xmlns:model="clr-namespace:MK.AgentWpf.Model"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:MainWindowModel x:Key="vm"/>
    </Window.Resources>
    <!--LayoutBegin-->
    <Grid DataContext="{Binding Source={StaticResource vm}}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <TreeView ItemsSource="{Binding Items}">
            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}" >
                    <Style.Triggers>
                        <Trigger Property="HasItems" Value="true">
                            <Setter Property="Focusable" Value="False"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TreeView.ItemContainerStyle>
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type model:RootNode}"
                              ItemsSource="{Binding Path=SubNodes}">
                    <Grid>
                        <TextBlock Text="{Binding Text}" />
                    </Grid>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type model:SubNodeItemWithCheckbox}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="20"/>
                            <ColumnDefinition/>
                        </Grid.ColumnDefinitions>
                        <CheckBox Grid.Column="0" IsChecked="{Binding IsSelected, Mode=TwoWay}" IsEnabled="{Binding IsEnabled,Mode=TwoWay}"/>
                        <TextBlock Text="{Binding Text}" Grid.Column="1"/>
                    </Grid>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type model:SubNode}">
                          
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>


        <Button Grid.Row="1" Width="30">
            <Image Source="/Images/Sign001.ico"/>
        </Button>
    </Grid>
</Window>

Und das Model dazu :

public class SubNodeItemWithCheckbox:INode
    {
        public SubNodeItemWithCheckbox(RootNode parent)
        {
            _parent = parent;
        }

        private RootNode _parent;

        private bool _isEnabled;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set { _isEnabled = value;OnPropertyChanged(() => IsEnabled); }
        }

        private bool _isSelected;
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            { 
                _isSelected = value;
                ChangeEnabledStatus();
                OnPropertyChanged(() => IsSelected); 
            }
        }

        private string _text;
        public string Text
        {
            get { return _text; }
            set { _text = value;OnPropertyChanged(() => Text); }
        }
        private void ChangeEnabledStatus()
        {
            foreach (INode subNode in _parent.SubNodes.Where(p => p.Text != _text))
            {
                subNode.IsEnabled = !_isSelected;
            }
        }

        #region OnPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged<T>(Expression<Func<T>> action)
        {
            var propertyName = GetPropertyName(action);
            OnPropertyChanged(propertyName);
        }

        private static string GetPropertyName<T>(Expression<Func<T>> action)
        {
            var expression = (MemberExpression)action.Body;
            var propertyName = expression.Member.Name;
            return propertyName;
        }

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                handler(this, e);
            }
        }
        #endregion


        
    }

Zwei Sachen erreicht : Templates für die beiden klassen und bei Anklicken der Checkbox werden die anderen Checkboxen Disabled.

Grüße
private Nachricht | Beiträge des Benutzers