1
votes

I have created a Treeview and used a stack panel to include a checkbox, icon image and text for each node in the tree. These nodes are created at runtime. I also have a button object. The xaml is below.

The problem i have is that, when the click me button is clicked, i need to traverse thru the tree view and if a checkbox is checked, perform some function.

Does anyone know how to find out if the checkbox for a node in the tree is checked, from the C# code behind ???

<Window x:Class="WPF_Explorer_Tree.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPF_Explorer_Tree" 
Title="KryptoG" Height="424" Width="815" Loaded="Window_Loaded">
<Window.Resources>
    <local:HeaderConverter x:Key="formatter" />
</Window.Resources>
<Grid>
    <TreeView x:Name="foldersItem" SelectedItemChanged="foldersItem_SelectedItemChanged" Background="#FFFFFFFF" BorderBrush="#FFFFFFFF" Foreground="#FFFFFFFF" Margin="0,0,236,112" AllowDrop="True" Visibility="Visible">
        <TreeView.Resources>
            <Style TargetType="{x:Type TreeViewItem}">
                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel Name="ST" Orientation="Horizontal">
                                <CheckBox VerticalAlignment="Center"  Name="SelectedCheckBox" IsChecked="False"  Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
                            <Image Name="img"  Width="20"  Stretch="Fill" 
                                   Source="{Binding 
                                   RelativeSource={RelativeSource 
                                   Mode=FindAncestor, 
                                   AncestorType={x:Type TreeViewItem}}, 
                                   Path=Header, 
                                   Converter={x:Static local:HeaderToImageConverter.InstanceIcon}}"       
                                   />
                                <TextBlock VerticalAlignment="Center" Text="{Binding 
                                   RelativeSource={RelativeSource 
                                   Mode=FindAncestor, 
                                   AncestorType={x:Type TreeViewItem}}, 
                                   Path=Header, 
                                   Converter={StaticResource formatter}}" 
                                     />
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TreeView.Resources>
    </TreeView>
    <TreeView HorizontalAlignment="Right" Margin="0,0,12,12" Name="treeView1" Width="204" AllowDrop="True" BorderBrush="White" Foreground="White" />
    <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,70" Name="button1" VerticalAlignment="Bottom" Width="75" Click="button1_Click">Click Me</Button>
    <Button Height="23" HorizontalAlignment="Left" Margin="267,0,0,69" Name="button2" VerticalAlignment="Bottom" Width="75" Click="button2_Click">Click Me too</Button>
</Grid>

2
What items are you putting in your TreeView?Josh G
TreeViewItems. Is that the answer? If not, let me know what other information do you need.trainer

2 Answers

7
votes

I would create a Two-Way data binding with that Check Box's IsChecked property to a ViewModel object instead. Much easier than navigating the tree.


Edit (per request of person asking):

Here's an example View Model (very simple that is only accounting for the IsChecked property):

public class ViewModel : System.ComponentModel.INotifyPropertyChanged
{
    private bool? _isChecekd;
    public bool? IsChecked
    {
        get { return _isChecekd; }
        set
        {
            if (_isChecekd != value)
            {
                _isChecekd = value;
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("IsChecked"));
                }
            }
        }
    }
    #region INotifyPropertyChanged Members
    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    #endregion
}

Now that you have an object implementing INotifyPropertyChanged, you can bind UI element properties to them. So you would update the IsChecked property of your CheckBox to this property. To do that, you first have to set the DataContext of Window1 in some way (or you could just do this on the TreeView itself as well). In your Window1.xaml.cs:

public Window1()
        {
            InitializeComponent();
            this.DataContext = new ViewModel();
        }

Then, in your Window1.xaml file, update the CheckBox IsChecked property:

<CheckBox VerticalAlignment="Center"  Name="SelectedCheckBox" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}"  Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />

And then, in whatever code you need to be able to interrogate the currently value of IsChecked, you can get to it this way (assuming this is Window1):

((ViewModel)this.DataContext).IsChecked

Hope that helps!

1
votes

I think Tony Heupel's answer is the best approach, but to understand it you need to know about the MVVM (Model-View-ViewModel) design pattern. I suggest you read this excellent article by Josh Smith