Benutzer mit den meisten Antworten
Probleme beim Finden (FindName) eines existierenden Controls

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); } }
- Als Antwort markiert Ouagadougou_Joe Freitag, 29. Juli 2011 09:30
Freitag, 29. Juli 2011 09:30
Alle Antworten
-
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:29Beantworter -
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:25Beantworter -
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:26Beantworter -
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
PathFreitag, 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); } }
- Als Antwort markiert Ouagadougou_Joe Freitag, 29. Juli 2011 09:30
Freitag, 29. Juli 2011 09:30