Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Treeview已扩展,但未启动_C#_Wpf_Mvvm_Treeview - Fatal编程技术网

C# Treeview已扩展,但未启动

C# Treeview已扩展,但未启动,c#,wpf,mvvm,treeview,C#,Wpf,Mvvm,Treeview,我正在尝试向TreeView添加捕获IsExpanded事件的功能。因此,当某个项目将展开时,它将在视图模型上引发属性或命令 这是我的密码: 我在viewmodel中还有一个属性用于IsExpanded(以及IsSelected),当我展开TreeviewItem时,这些属性都不会出现。 有什么想法吗 感谢大家,当节点展开且一切正常时,尝试重现问题并实现调用命令的附加行为。解决方案的完整代码: XAML <Window x:Class="TreeViewTest.MainWindow"

我正在尝试向
TreeView
添加捕获
IsExpanded
事件的功能。因此,当某个项目将展开时,它将在视图模型上引发属性或命令

这是我的密码:


我在viewmodel中还有一个属性用于
IsExpanded
(以及IsSelected),当我展开
TreeviewItem
时,这些属性都不会出现。 有什么想法吗


感谢大家,当节点展开且一切正常时,

尝试重现问题并实现调用命令的附加行为。解决方案的完整代码:

XAML

<Window x:Class="TreeViewTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:sotc="clr-namespace:TreeViewTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <sotc:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <TreeView  Name="ScenariosTreeView" ItemsSource="{Binding Path=Cat, Mode=TwoWay}" Focusable="True" >
            <TreeView.InputBindings>
                <KeyBinding Key="Delete" Command="{Binding DeleteCommand}" CommandParameter="{Binding SelectedValue ,ElementName=ScenariosTreeView}" />
            </TreeView.InputBindings>

            <TreeView.ItemContainerStyle>
                <Style TargetType="{x:Type TreeViewItem}">
                    <Setter Property="IsExpanded" Value="{Binding IsExtended, Mode=TwoWay}" />
                    <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
                    <Setter Property="sotc:Behaviours.ExpandingBehaviour" Value="{Binding DataContext.ExpandingCommand, RelativeSource={RelativeSource AncestorType=Window}}"/>
                </Style>
            </TreeView.ItemContainerStyle>

            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type sotc:ScenarioCategory}" ItemsSource="{Binding Path=ScenarioList}" >
                    <TextBlock  Text="{Binding Path=Name}" Foreground="Black" IsEnabled="True" Focusable="True"/>
                </HierarchicalDataTemplate>

                <DataTemplate DataType="{x:Type sotc:Scenario}" >
                    <TextBlock  Text="{Binding Path=Name, Mode=TwoWay}" />
                </DataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

C#

公共类ViewModelBase:INotifyPropertyChanged
{
public void OnPropertyChanged([CallerMemberName]字符串名称=null)
{
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(名称));
}
公共事件属性更改事件处理程序属性更改;
}
公共类MainWindowViewModel:ViewModelBase
{
公共ICommand ExpandingCommand{get;set;}
私有void executeexpanding命令(对象obj)
{
Console.WriteLine(@“扩展”);
}
私有布尔CANEXECUTEEEXPANDING命令(对象obj)
{
返回true;
}
公共主窗口视图模型()
{
ExpandingCommand=newrelaycommand(ExecuteExpandingCommand、CanExecuteExpandingCommand);
Cat=新的可观察集合(新场景类别[]
{
新场景类别{Name=“C1”},新场景类别{Name=“C2”},新场景类别{Name=“C3”}
});
}
公共可观测集合Cat{get;set;}
}
公共类场景类别:ViewModelBase
{
字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置{u name=value;OnPropertyChanged();}
}
布尔扩展;
公共事业扩大了
{
获取{return\u isExtended;}
设置
{
_isExtended=值;
Console.WriteLine(@“扩展集”);
OnPropertyChanged();
}
}
布尔乌当选;
公选学校
{
获取{return}isSelected;}
设置
{
_isSelected=值;
控制台写入线(@“IsSelected set”);
OnPropertyChanged();
}
}
公共ObservableCollection场景列表{get;set;}
公共场景类别()
{
ScenarioList=new ObservableCollection(新场景[]{new Scenario{Name=“1”},新场景{Name=“2”},新场景{Name=“3”});
}
}
公共类场景:ViewModelBase
{
字符串\u名称;
公共字符串名
{
获取{return\u name;}
设置{u name=value;OnPropertyChanged();}
}
布尔扩展;
公共事业扩大了
{
获取{return\u isExtended;}
设置
{
_isExtended=值;
OnPropertyChanged();
}
}
布尔乌当选;
公选学校
{
获取{return}isSelected;}
设置
{
_isSelected=值;
OnPropertyChanged();
}
}
}
公众静态阶级行为
{
公共静态只读从属属性ExpandingBehaviorProperty=
DependencyProperty.RegisterAttached(“扩展行为”)、typeof(ICommand)、typeof(行为),
新属性元数据(OneExpandingBehavior已更改);
公共静态void setExpandingBehavior(DependencyObject o、ICommand值)
{
o、 SetValue(ExpandingBehavior属性,值);
}
公共静态ICommand GetExpandingBehavior(DependencyObject o)
{
返回(ICommand)o.GetValue(ExpandingBehavior属性);
}
私有静态void OneExpandingBehavior已更改(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
TreeViewItem tvi=d作为TreeViewItem;
如果(tvi!=null)
{
ICommand ic=e.NewValue作为ICommand;
如果(ic!=null)
{
tvi.扩展+=(s,a)=>
{
if(ic.CanExecute(a))
{
ic.执行(a);
}
a、 已处理=正确;
};
}
}
}
}
公共类中继命令:ICommand
{
私人行动执行;
私人职能执行;
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
公共RelayCommand(执行操作,Func canExecute=null)
{
this.execute=execute;
this.canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
返回this.canExecute==null | | this.canExecute(参数);
}
public void Execute(对象参数)
{
执行(参数);
}
}

找到了答案。如果事件放置在表示为treeviewItem的对象中,而不是视图模型中,则会触发该事件

您的
场景
对象是您的视图模型吗?有一个列表,其中viewmodel和treeview显示列表使用
模板绑定
和非
绑定
当您在树上单击时,您的XAML看起来很好,并且应在viewmodel中设置IsExtended和IsSelected属性。您可以在VisualStudio中查看输出窗口,可能存在绑定错误,例如
public class ViewModelBase : INotifyPropertyChanged
{

    public void OnPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class MainWindowViewModel : ViewModelBase
{
    public ICommand ExpandingCommand { get; set; }

    private void ExecuteExpandingCommand(object obj)
    {
        Console.WriteLine(@"Expanded");
    }
    private bool CanExecuteExpandingCommand(object obj)
    {
        return true;
    }

    public MainWindowViewModel()
    {
        ExpandingCommand = new RelayCommand(ExecuteExpandingCommand, CanExecuteExpandingCommand);

        Cat = new ObservableCollection<ScenarioCategory>(new ScenarioCategory[] 
        {
            new ScenarioCategory { Name = "C1" }, new ScenarioCategory { Name = "C2" }, new ScenarioCategory { Name = "C3" }
        });
    }

    public ObservableCollection<ScenarioCategory> Cat { get; set; }
}


public class ScenarioCategory : ViewModelBase
{
    string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged(); }
    }

    bool _isExtended;
    public bool IsExtended
    {
        get { return _isExtended; }
        set
        {
            _isExtended = value;
            Console.WriteLine(@"IsExtended set");
            OnPropertyChanged();
        }
    }

    bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            Console.WriteLine(@"IsSelected set");
            OnPropertyChanged();
        }
    }

    public ObservableCollection<Scenario> ScenarioList { get; set; }

    public ScenarioCategory()
    {
        ScenarioList = new ObservableCollection<Scenario>(new Scenario[] { new Scenario { Name = "1" }, new Scenario { Name = "2" }, new Scenario { Name = "3" } });
    }

}

public class Scenario : ViewModelBase
{
    string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged(); }
    }

    bool _isExtended;
    public bool IsExtended
    {
        get { return _isExtended; }
        set
        {
            _isExtended = value;
            OnPropertyChanged();
        }
    }

    bool _isSelected;
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged();
        }
    }
}


public static class Behaviours
{
    public static readonly DependencyProperty ExpandingBehaviourProperty =
        DependencyProperty.RegisterAttached("ExpandingBehaviour", typeof(ICommand), typeof(Behaviours),
            new PropertyMetadata(OnExpandingBehaviourChanged));


    public static void SetExpandingBehaviour(DependencyObject o, ICommand value)
    {
        o.SetValue(ExpandingBehaviourProperty, value);
    }
    public static ICommand GetExpandingBehaviour(DependencyObject o)
    {
        return (ICommand)o.GetValue(ExpandingBehaviourProperty);
    }
    private static void OnExpandingBehaviourChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TreeViewItem tvi = d as TreeViewItem;
        if (tvi != null)
        {
            ICommand ic = e.NewValue as ICommand;
            if (ic != null)
            {
                tvi.Expanded += (s, a) =>
                {
                    if (ic.CanExecute(a))
                    {
                        ic.Execute(a);

                    }
                    a.Handled = true;
                };
            }
        }
    }
}


public class RelayCommand : ICommand
{
    private Action<object> execute;
    private Func<object, bool> canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
}