0
votes

I created a WPF application where I create a list of items to be executed, as a Treeview. On a click event, I parse the ObservableCollection items one by one. This observableCollection is set as the DataContext for the treeview. When running the tests, I want to highlight the current running item in the Treeview.

I have the implemented following code, but the highlighting on the Treeview (visuallY) does not seem to happen. I checked that the "IsSelected" property does get set/unset as programmed.

I am not sure were I went wrong. Could you point out where the mistake is.

I have this class used as a DataContext to the TreeView (named mainTree).

class mytreefile : INotifyPropertyChanged
{
    private string _name { get; set; }
    
    public ObservableCollection <mytreefile> children { get; set; }
    
    bool? _isSelected = false;
    public bool? IsSelected
    {
        get { return _isSelected; }
        set { SetIsSelected(value); }
    }
    void SetIsSelected(bool? val)
    {
        _isSelected = val;
    }
    
    public mytreefile(string value)
    {
        _name = value;
        children = new ObservableCollection<mytreefile>();
    }
    
     void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

        public event PropertyChangedEventHandler PropertyChanged;
}

The XAML file is

<Grid.Resources>
    <ResourceDictionary>
        <HierarchicalDataTemplate x:Key="tvTemplate" ItemsSource="{Binding children, Mode=TwoWay}">
            <StackPanel Orientation="Horizontal">
                <ContentPresenter Content="{Binding _name, Mode=TwoWay}" Margin="2,0" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </ResourceDictionary>
</Grid.Resources>

<TreeView x:Name="mainTree" Grid.Row="0" Grid.Column="0" Grid.RowSpan="4" Background="WhiteSmoke"
            Height="Auto" Width="Auto"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
            HorizontalContentAlignment="Stretch"                         
            Margin="1,0,2,0" SelectedItemChanged="mainTree_SelectedItemChanged"
            ItemTemplate="{StaticResource tvTemplate}" 
            ItemsSource="{Binding}" DataContext="{Binding nodes}">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
                <Trigger Property="IsSelected" Value="False">
                    <Setter Property="FontWeight" Value="Normal" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </TreeView.ItemContainerStyle>
</TreeView>

And my MainWindow code is:

public partial class MainWindow : Window
{
    ObservableCollection<mytreefile> nodes = new ObservableCollection<mytreefile>();
    mytreefile mtf = null;
    Thread thThread = null;
    int gnCount = 0;
    
    private void LoadTree ()
    {
        mytreefile tf1 = new mytreefile("Group1");
        nodes.Add(tf1);
        
        mytreefile subtf1 = new mytreefile("Sub Item 1");
        mytreefile subtf2 = new mytreefile("Sub Item 2");
        mytreefile subtf3 = new mytreefile("Sub Item 3");
        mytreefile subtf4 = new mytreefile("Sub Item 4");
        
        tf1.children.Add(subtf1); tf1.children.Add(subtf2); tf1.children.Add(subtf3); tf1.children.Add(subtf4);
        
        maintree.DataContext = nodes;
    }
    
    private void OnButton1_click()
    {
        mtf = nodes.ElementAt(0);
        gnCount = 0;
        thThread = new Thread(new ThreadStart(this.myThread));
        thThread.Start();
    }
    public void myThread ()
    {
        for (int i = 0; i < 3; i++)
        {
            Thread.Sleep(1000);
            this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send,
                            new Action(() => SetTreeItem(i)));
        }
    }
    
    public void SetTreeItem(int i)
    {   
        if (gnCount > 0) {
            mytreefile mtreeitem = mtf.children.ElementAt(gnCount-1);
            mtreeitem.IsSelected = false;
        }
        mytreefile mtreeitem = mtf.children.ElementAt(gnCount++);
        mtreeitem.IsSelected = true;
    }
}
1

1 Answers

0
votes

The problem was with the "mytreefile" class. The below class works fine. The way the "IsSelected" implementation was done made the difference. Posting the code for reference.

class mytreefile : INotifyPropertyChanged
{
    private string _name { get; set; }
    
    public ObservableCollection <mytreefile> children { get; set; }
    
    private bool _isSelected;

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            if (value != this._isSelected)
            {
                this._isSelected = value;
                NotifyPropertyChanged("IsSelected");
            }
        }
    }
    
    public mytreefile(string value)
    {
        _name = value;
        children = new ObservableCollection<mytreefile>();
    }
    
     void NotifyPropertyChanged(string info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

        public event PropertyChangedEventHandler PropertyChanged;
}