Невозможно программно установить выбранный элемент Custom TreeView в Treeview - PullRequest
0 голосов
/ 12 июля 2020

Я создал приложение WPF, в котором я создаю список элементов для выполнения в виде Treeview. В событии щелчка я анализирую элементы ObservableCollection один за другим. Этот observableCollection устанавливается как DataContext для древовидного представления. При запуске тестов я хочу выделить текущий выполняющийся элемент в Treeview.

У меня реализован следующий код, но выделения в Treeview (visuallY), похоже, не происходит. Я проверил, что свойство "IsSelected" действительно устанавливается / не устанавливается, как запрограммировано.

Я не уверен, что я ошибся. Не могли бы вы указать, где ошибка.

У меня этот класс используется как DataContext для TreeView (с именем 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;
}

Файл XAML - это

<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>

И мой код MainWindow:

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 Ответ

0 голосов
/ 12 июля 2020

Проблема была с классом mytreefile. Приведенный ниже класс отлично работает. То, как была реализована реализация IsSelected, имело значение. Размещение кода для справки.

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;
}
...