locked
Probleme beim Finden (FindName) eines existierenden Controls RRS feed

  • Frage

  •     <ListBox x:Name="Layerlist" ItemsSource="{Binding ElementName=map, Path=Layers.[0].Layers}" Margin="5,0" FontWeight="Normal" Grid.Row="1" Grid.RowSpan="2">
          <ListBox.ItemsPanel>
            <ItemsPanelTemplate VirtualizingStackPanel.VirtualizationMode="Standard" />
          </ListBox.ItemsPanel>
          <ListBox.ItemTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <CheckBox Margin="2" x:Name="TOCCheckBox" Content="{Binding Name}" Tag="{Binding ID}" ClickMode="Press" Click="CheckBox_Click2" IsChecked="{Binding DefaultVisibility}"/>
              </StackPanel>
            </DataTemplate>
          </ListBox.ItemTemplate>
        </ListBox>
    

    Ich habe in meiner Anwendung eine Listbox über oben angezeigten code erstellt. Innerhalb der Listbox existieren somit verschiedene Checkboxen. Nun möchte ich im Code auf spezifische Checkboxen zugreifen können, deren Tag mir bekannt ist. Allerdings habe ich Probleme die Checkboxen ansich anzusprechen.
    Habe bereits FindName und den Weg über den VisualTreeHelper versucht, der mir allerings nur fehler oder als Child-Elements der Listbox Grid, Border, und ScrollViewer anzeigt(??) aber keine Checkboxen?

    Wie kann ich die Checkboxen ansprechen?

    Donnerstag, 28. Juli 2011 09:39

Antworten

  • So ich hab das ganze jetzt gelöst indem ich den VisualTree der ListBox komplett durchlaufe und die elemente die Checkboxen sind nach ihrem Tag abfrage.

    void PrintVisualTree(DependencyObject element, int level)
        {
          if (element.GetType().Name == "CheckBox")
          {
            CheckBox C = element as CheckBox;
            if (C.Tag.ToString() == Layerindex.ToString())
            {
              if (C.IsChecked == false)
              {
                C.IsChecked = true;
              }
              else
              {
                C.IsChecked = false;
              }
    
            }
    
          }
          int children = VisualTreeHelper.GetChildrenCount(element);
          for (int i = 0; i < children; i++)
          {
            DependencyObject child = VisualTreeHelper.GetChild(element, i);
            PrintVisualTree(child, ++level);
          }
        }
    

     

    Freitag, 29. Juli 2011 09:30

Alle Antworten

  • Was genau möchtest du denn mit den Checkboxen machen?
    Donnerstag, 28. Juli 2011 11:04
    Beantworter
  • Eigentlich nur was völlig banales. Bei Klick auf einen Button möchte ich in der entsprechend getaggten Checkbox den Haken setzen, oder nicht.

    Der Tag der Checkboxen ist durchnummeriert. Die Anzahl der Checkboxen verändert sich ja dynamisch. Sind es drei werden sie mit 0, 1, 2 getagged.

    Donnerstag, 28. Juli 2011 13:02
  • Dazu könntest du doch die Datenquelle ändern und das IsChecked Property der CheckBox an ein neues Property in deinem Objektmodell binden.
    <CheckBox Margin="2" x:Name="TOCCheckBox" Content="{Binding Name}" Tag="{Binding ID}" ClickMode="Press" Click="CheckBox_Click2" IsChecked="{Binding DefaultVisibility}"
    IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" />
    
    




    Freitag, 29. Juli 2011 06:29
    Beantworter
  • Das IsChecked Property muss leider an andere Objekte gebunden bleiben. Ich glaube ich muss doch weiter ausholen :)

    In meiner App habe ich eine Karte mit mehreren Darstellungsebenen. Diese Ebenen haben die IDs 1,2,3,4,5 usw. . Für jede Ebene wird in einer Listbox eine Checkbox erzeugt, deren Tag den Ebenen IDs entspricht. Auf diese Weise sind die Checkboxen und Ebenen miteinander verbudnen, und ich kann die Ebenen an- bzw. ausschalten.
    Beim Start der Anwendung wird geguckt welche Ebenen aktiv sind und über das "IsChecked" Protperty werden die Checkboxen dann angehakt oder nicht.

    Nun möchte ich aber auch über Buttons die Ebenen an- bzw. ausschalten können. Das funktioniert auch gut, nur muss eben gleichzeitig auch der Haken aus der entsprechenden Checkbox entfernt werden.

    Bsp: Klick des BUttons1 führt zur ausschaltung der Ebene mit der ID1. Gleichzeitig muss nun auch die Checkbox mit dem Tag 1 ausgehakt werden.

    Ich hoffe mein Problem ist nun klarer geworden.

    Freitag, 29. Juli 2011 06:52
  • Ok. An welche Objekte bindest du denn das IsChecked?
    Am einfachsten ist es wenn du ein View - Objekt hättest und dieses dann an alle Controls bindest. Dann ändert sich bei Check der CheckBox oder Click eines Buttons immer nur
    das Objekt und alle Controls, die an das View - Objekt gebunden sind passen sich an.
    Hier mal ein ungetestes Beispiel:

      public class ViewManager : INotifyPropertyChanged
      {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
          var handler = PropertyChanged;
          if (handler != null)
          {
            handler(this, new PropertyChangedEventArgs(propertyName));
          }
        }
    
        private bool _layer1Enabled;
        public bool Layer1Enabled
        {
          get
          {
            return _layer1Enabled; 
          }
          set
          {
            _layer1Enabled = value;
            this.OnPropertyChanged("Layer1Enabled");
          }
        }
    
        private bool _layer2Enabled;
        public bool Layer2Enabled
        {
          get
          {
            return _layer2Enabled;
          }
          set
          {
            _layer2Enabled = value;
            this.OnPropertyChanged("Layer2Enabled");
          }
        }
        //Weitere Layer implementieren
    
    
        private RelayCommand _isLayer1EnabledCommand;
        public RelayCommand IsLayer1EnabledCommand
        {
          get
          {
            if (_isLayer1EnabledCommand == null)
            {
              _isLayer1EnabledCommand = new RelayCommand(
                () => 
                  {
                    if (this.Layer1Enabled)
                      this.Layer1Enabled = false;
                    else
                      this.Layer1Enabled = false;
                  });
    
            }
            return _isLayer1EnabledCommand;
          }
        }
    
        private RelayCommand _isLayer2EnabledCommand;
        public RelayCommand IsLayer2EnabledCommand
        {
          get
          {
            if (_isLayer2EnabledCommand == null)
            {
              _isLayer2EnabledCommand = new RelayCommand(
                () =>
                {
                  if (this.Layer2Enabled)
                    this.Layer2Enabled = false;
                  else
                    this.Layer2Enabled = false;
                });
    
            }
            return _isLayer2EnabledCommand;
          }
        }
      }
    


        <Grid DataContext="{Binding ViewManager}">
          
          <ListBox x:Name="Layer1" IsEnabled="{Binding IsLayer1Enabled, Mode=TwoWay}">
            <ListBox.Items>
              <CheckBox IsChecked="{Binding Path=IsLayer1Enabled, Mode=TwoWay}" />
            </ListBox.Items>
          </ListBox>
          <ListBox x:Name="Layer2" IsEnabled="{Binding IsLayer2Enabled, Mode=TwoWay}">
            <ListBox.Items>
              <CheckBox IsChecked="{Binding Path=IsLayer2Enabled, Mode=TwoWay}" />
            </ListBox.Items>
          </ListBox>
          
          <Button Content="Layer1 ein/ausschalten">
            <i:Interaction.Triggers>
              <i:EventTrigger EventName="Click">
                <mvvm:EventToCommand Command="{Binding Path=IsLayer1EnabledCommand}"/>
              </i:EventTrigger>
            </i:Interaction.Triggers>        
          </Button>
    
          <Button Content="Layer2 ein/ausschalten">
            <i:Interaction.Triggers>
              <i:EventTrigger EventName="Click">
                <mvvm:EventToCommand Command="{Binding Path=IsLayer2EnabledCommand}"/>
              </i:EventTrigger>
            </i:Interaction.Triggers>
          </Button>
          
        </Grid>
    

    Freitag, 29. Juli 2011 07:25
    Beantworter
  • Das IsChecked der Checkboxen ist an die DefaultVisibilityProperty des Layers gebunden. Leider gibts aber nur die Defaultvisiblity Property und keine VisibilityProperty, welche den Status der Ebenen ständig überwacht.

    Ehrlich gesagt muss ich deinen Code erstmal länger versuchen zu verstehen ;) Aber schonmal danke für die Hilfe.

    Ich verstehe aber nicht so ganz, wieso ich über den VisualTreeHelper nicht auf die CheckBoxen komme? Über den selben Weg greife ich auch auf das Image der Buttons innerhalb einer ListBox zu.

    Ich hatte mir vorgestellt einfach bei Klick auf den Button sagen zu können: Entferne den Haken bei Checkbox mit Tag 1. Aber das war wohl zu einfach gedacht.

    Freitag, 29. Juli 2011 08:10
  • Evtl. kannst du die CheckBox nicht finden, da Standardmäßig ein VirtualizingStackPanel verwendest. Teste dochmal ein normales StackPanel:

    <ListBox.ItemsPanel>

    <ItemsPanelTemplate>

    <StackPanel Orientation="Horizontal"/>

    </ItemsPanelTemplate>

    </ListBox.ItemsPanel>


    Freitag, 29. Juli 2011 08:26
    Beantworter
  • Ich hab mir jetzt mal alle Children der ListBox ausgeben lassen. Und doch verwundert wieviel da drin stecken soll. Aber ne Checkbox is auch dabei:

    ListBox
      Grid
        Border
          ScrollViewer
            Border
              Grid
                ScrollContentPresenter
                  ItemsPresenter
                    StackPanel
                      ListBoxItem
                        Grid
                          Rectangle
                            Rectangle
                              ContentPresenter
                                Grid
                                  StackPanel
                                    CheckBox
                                      Grid
                                        Grid
                                          Rectangle
                                            Rectangle
                                              Rectangle
                                                Rectangle
                                                  Rectangle
                                                    Path
                                                      Rectangle
                                                        Rectangle
                                                          Rectangle
                                                            Border
                                                              Grid
                                                                Path
                                                                  Path
                                          ContentPresenter
                                            Grid
                                              TextBlock
                                Rectangle
                        ListBoxItem
                          Grid
                            Rectangle
                              Rectangle
                                ContentPresenter
                                  Grid
                                    StackPanel
                                      CheckBox
                                        Grid
                                          Grid
                                            Rectangle
                                              Rectangle
                                                Rectangle
                                                  Rectangle
                                                    Rectangle
                                                      Path
                                                        Rectangle
                                                          Rectangle
                                                            Rectangle
                                                              Border
                                                                Grid
                                                                  Path
                                                                    Path
                                            ContentPresenter
                                              Grid
                                                TextBlock
                                  Rectangle
                  Rectangle
                    ScrollBar
                      ScrollBar
          Border
            Grid
              Path
                Path

     

     

    Freitag, 29. Juli 2011 08:58
  • So ich hab das ganze jetzt gelöst indem ich den VisualTree der ListBox komplett durchlaufe und die elemente die Checkboxen sind nach ihrem Tag abfrage.

    void PrintVisualTree(DependencyObject element, int level)
        {
          if (element.GetType().Name == "CheckBox")
          {
            CheckBox C = element as CheckBox;
            if (C.Tag.ToString() == Layerindex.ToString())
            {
              if (C.IsChecked == false)
              {
                C.IsChecked = true;
              }
              else
              {
                C.IsChecked = false;
              }
    
            }
    
          }
          int children = VisualTreeHelper.GetChildrenCount(element);
          for (int i = 0; i < children; i++)
          {
            DependencyObject child = VisualTreeHelper.GetChild(element, i);
            PrintVisualTree(child, ++level);
          }
        }
    

     

    Freitag, 29. Juli 2011 09:30