gpt4 book ai didi

c# - 自定义 Treeview 用户控件 MVVM 双击冒泡事件 WPF

转载 作者:太空宇宙 更新时间:2023-11-03 11:18:16 29 4
gpt4 key购买 nike

我正在尝试制作自定义 TreeView 并将其设为用户控件。当我将用户控件包装在另一个窗口中时,我试图在主窗口中获取 TreeView 项目双击事件。

<Window xmlns:avalondock="http://avalondock.codeplex.com"     x:Class="WellsVisualizationWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:well="clr-namespace:VisualizationWPF.ViewModel.ViewUserControl"
Title="e-IFD" Height="408" Width="558" WindowState="Maximized"
>
<Grid MinWidth="100" **TreeViewItem.MouseLeftButtonClick=<EventHandler>**> <-- Trying to override but failed :p
<local:CustomTreeView />
</Grid>

我试图从 CustomTreeView 项目中获取冒泡鼠标双击,并在用户控件外的网格包装器中拦截该事件。我试图添加 TreeViewItem。 TreeViewItem.MouseLeftButtonDown="Grid_MouseLeftButtonDown 失败。有什么办法可以解决我的问题吗?

这是我的 TreeView 自定义用户控件的代码

<UserControl x:Class="WellsVisualizationWPF.ViewModel.ViewUserControl.WellsTreeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:VisualizationWPF.ViewModel"
>
<Grid MinWidth="100">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="500" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="1">
<TextBlock TextWrapping="Wrap" FontSize="12">
Text1
</TextBlock>
<Button Height="24" Content="Add New" Name="btn_add" Click="btn_add_Click" />
</StackPanel>
<ScrollViewer>
<DockPanel>
<TreeView Grid.Row="0" ItemsSource="{Binding Data}">
<TreeView.Resources>
<HierarchicalDataTemplate
DataType="{x:Type local:MainViewModel}"
ItemsSource="{Binding Children}"
>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type local:ParamsViewModel}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</TreeView.Resources>
</TreeView>
</DockPanel>
</ScrollViewer>
</Grid>

最佳答案

您根本不需要在用户控件之外发布双击事件。您需要添加一些 InputBinding (在这种特殊情况下为 MouseBinding)到 InputBindings收藏TreeView.SelectedItem .

问题是您不能以正常、明显的方式做到这一点 - 通过 TreeView.ItemContainerStyle 设置 InputBindings,因为 InputBindings 集合是只读的。悲伤,但真实。

好消息是您可以使用附加属性来实现这一点。示例:

查看模型。
a) 这是将在 TreeView 中显示为项目的内容:

public class Node : ViewModelBase
{
public String Text
{
get { return text; }
set
{
if (text != value)
{
text = value;
OnPropertyChanged("Text");
}
}
}
private String text;

public ObservableCollection<Node> Nodes { get; set; }
}

b) 这是“主” View 模型:

public class ViewModel : ViewModelBase
{
public ViewModel()
{
this.selectedNodeDoubleClickedCommand = new RelayCommand<Node>(node =>
{
Debug.WriteLine(String.Format("{0} clicked!", node.Text));
});
}

public ObservableCollection<Node> Nodes { get; set; }

public RelayCommand<Node> SelectedNodeDoubleClickedCommand
{
get { return selectedNodeDoubleClickedCommand; }
}
private readonly RelayCommand<Node> selectedNodeDoubleClickedCommand;
}

用户控制代码隐藏。基本思想——我们添加了一个附加属性来通过它在 XAML 中设置输入绑定(bind),另一个附加属性——在输入绑定(bind)触发时允许外部世界绑定(bind)命令:

public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}

public ICommand SelectedItemDoubleClickedCommand
{
get { return (ICommand)GetValue(SelectedItemDoubleClickedCommandProperty); }
set { SetValue(SelectedItemDoubleClickedCommandProperty, value); }
}

public static readonly DependencyProperty SelectedItemDoubleClickedCommandProperty = DependencyProperty.Register(
"SelectedItemDoubleClickedCommand", typeof(ICommand),
typeof(UserControl1),
new UIPropertyMetadata(null));

public static ICommand GetSelectedItemDoubleClickedCommandAttached(DependencyObject obj)
{
return (ICommand)obj.GetValue(SelectedItemDoubleClickedCommandAttachedProperty);
}

public static void SetSelectedItemDoubleClickedCommandAttached(DependencyObject obj, ICommand value)
{
obj.SetValue(SelectedItemDoubleClickedCommandAttachedProperty, value);
}

public static readonly DependencyProperty SelectedItemDoubleClickedCommandAttachedProperty = DependencyProperty.RegisterAttached(
"SelectedItemDoubleClickedCommandAttached",
typeof(ICommand), typeof(UserControl1),
new UIPropertyMetadata(null, SelectedItemDoubleClickedCommandAttachedChanged));

private static void SelectedItemDoubleClickedCommandAttachedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var item = d as TreeViewItem;
if (item != null)
{
if (e.NewValue != null)
{
var binding = new MouseBinding((ICommand)e.NewValue, new MouseGesture(MouseAction.LeftDoubleClick));

BindingOperations.SetBinding(binding, InputBinding.CommandParameterProperty, new Binding("SelectedItem")
{
RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(TreeView), 1)
});

item.InputBindings.Add(binding);
}
}
}
}

用户控制 XAML:

<Grid>
<TreeView ItemsSource="{Binding Nodes}">
<TreeView.Resources>
<HierarchicalDataTemplate ItemsSource="{Binding Nodes}" DataType="{x:Type local:Node}">
<TextBlock Text="{Binding Text}"/>
</HierarchicalDataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="local:UserControl1.SelectedItemDoubleClickedCommandAttached"
Value="{Binding SelectedItemDoubleClickedCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}" />
</Style>
</TreeView.ItemContainerStyle>

</TreeView>
</Grid>

主窗口 XAML:

<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication2"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 SelectedItemDoubleClickedCommand="{Binding SelectedNodeDoubleClickedCommand}"/>
</Grid>
</Window>

主窗口代码隐藏:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel
{
Nodes = new ObservableCollection<Node>
{
new Node
{
Text = "Parent 1",
Nodes = new ObservableCollection<Node>
{
new Node { Text = "Child 1.1"},
new Node { Text = "Child 1.2"},
}
},
new Node
{
Text = "Parent 2",
Nodes = new ObservableCollection<Node>
{
new Node { Text = "Child 2.1"},
new Node { Text = "Child 2.2"},
}
},
}
};
}
}

关于c# - 自定义 Treeview 用户控件 MVVM 双击冒泡事件 WPF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11926954/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com