C# Listview MouseDoubleClickEvent在后台代码中创建
当我有:C# Listview MouseDoubleClickEvent在后台代码中创建,c#,wpf,listview,code-behind,C#,Wpf,Listview,Code Behind,当我有: <UserControl.Resources> <Style x:Key="itemstyle" TargetType="{x:Type ListViewItem}"> <EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClick" /> <Setter Property="HorizontalContentAlignment" Val
<UserControl.Resources>
<Style x:Key="itemstyle" TargetType="{x:Type ListViewItem}">
<EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClick" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
</Style>
</UserControl.Resources>
<Grid>
<ListView ItemContainerStyle="itemstyle" Name="listView1" >
<ListView.View>
<GridView>
... etc
一切都很好。
现在我需要对代码隐藏做同样的事情。这就是我得出的结论:
public Constructor(){
listview.AddHandler(
ListViewItem.MouseDoubleClickEvent,
new MouseButtonEventHandler(HandleDoubleClick)
);
}
protected void HandleDoubleClick(object sender, MouseButtonEventArgs e)
{
T item = (T)(((ListViewItem)sender).Content);
// error cause the sender is the listview
}
当我双击listview的任何部分而不仅仅是listviewItem时,会触发该事件。另外,我希望发件人是ListViewItem,而不是。发送方实际上是listview。我尝试过的事情: 1) 因为发件人是listview,所以我尝试将事件创建为: 我得到了相同的错误,发送者是listview 2) 而不是做: 我有: 问题是,如果用户双击listview中非该行的任何内容,它将返回当前选定的项目
为什么我的代码不起作用?我做错了什么?在xaml中,将事件处理程序附加到ListViewItem,而在代码隐藏中,将其附加到ListView本身。这就是为什么你会有不同的行为。如果要在代码隐藏中执行相同的操作,则必须循环items集合中的所有项,并将每个项的双击事件绑定到处理程序
如果没有真正的理由在代码隐藏中这样做,我会选择更适合MVVM模式的xaml方法,您可以尝试在代码隐藏中保留尽可能少的代码。在xaml中,您将事件处理程序附加到ListViewItem,而在代码隐藏中,您将其附加到ListView本身。这就是为什么你会有不同的行为。如果要在代码隐藏中执行相同的操作,则必须循环items集合中的所有项,并将每个项的双击事件绑定到处理程序
如果没有真正的理由在代码隐藏中这样做,我会选择更适合MVVM模式的xaml方法,您可以尝试在代码隐藏中保留尽可能少的代码。不明白为什么要在代码隐藏中这样做,除非您希望在UserControl中包含命名内容,所以您要将其更改为自定义控件。尝试在代码隐藏中重复xaml代码,即为ListViewItem创建一个样式,并将其设置为listview的ItemContainerStyle。不明白为什么要在代码隐藏中执行此操作,除非您希望UserControl中包含命名内容,所以要将其更改为自定义控件。尝试在代码隐藏中重复xaml代码,即为ListViewItem创建样式,并将其设置为listview的ItemContainerStyle
我认为你应该使用依附行为,因为
创建ListViewItemDoubleClickCommandBehavior 如上图所示,这个
CommandBehavior
类将命令链接到控件
- 在上面的例子中,它是一个按钮库,但我们要制作一个ListViewItem
- 这一个需要prism,因为它继承的CommandBehaviorBase是该库的一部分。您可以全部获得(但对于本例,您只需要使用Prism.dll命令)
- 命名约定要求您应以以下格式命名此CommandBehavior
X—将命令绑定到的控件的名称(在本例中为ListViewItem)[X][Y]CommandBehavior
Y-用户执行的导致命令发生的操作(在本例中,双击)
public class ListViewItemDoubleClickCommandBehaviour : CommandBehaviorBase<ListViewItem>
{
public ListViewItemDoubleClickCommandBehaviour(ListViewItem controlToWhomWeBind)
: base(controlToWhomWeBind)
{
controlToWhomWeBind.MouseDoubleClick += OnDoubleClick;
}
private void OnDoubleClick(object sender, System.Windows.RoutedEventArgs e)
{
ExecuteCommand();
}
}
注:
我知道这看起来像是很多复杂的代码,但一旦您足够频繁地使用它,它就是一个简单的模式,它将所有的复杂性从视图模型中抽象出来,因此命令到控件的绑定看起来非常简单
在viewmodel中创建命令,并在xaml中绑定到该命令 现在繁重的工作结束了,我们做简单的部分 创建命令 我假设您熟悉命令,您可以像往常一样创建命令:
public ICommand DisplaySelectedItemCmd { get; protected set; }
//This method goes in your constructor
private void InitializeCommands()
{
//Initializes the command
this.DisplaySelectedItemCmd = new RelayCommand(
(param) =>
{
this.DisplaySelectedItem((object)param);
},
(param) => { return this.CanDisplaySelectedItem; }
);
}
//The parameter should be your listview's selected item. I have no idea what type it is so I made it an object
public void DisplaySelectedPolicy(object selectedListViewItem)
{
//Code to perform when item is double clicked
}
private bool CanDisplaySelectedPolicy
{
get
{
return true; //Change this bool if you have any reason to disable the double clicking, as this bool basically is linked to the double click command firing.
}
}
在xaml中创建绑定
现在来看精彩的部分。
首先添加xml名称空间:
xmlns:commands="clr-namespace:CommandHandling"
然后在ListViewItem上绑定
<Style TargetType="{x:Type ListViewItem}" x:Key="{x:Type ListViewItem}" >
<Setter Property="commands:DoubleClick.Command" Value="{Binding Path=bleh}"/>
</Style>
完成了
如果这不起作用,请告诉我。(将来读到这篇文章的人,如果你愿意,可以向我寻求帮助)
u_
我认为你应该使用依附行为,因为
创建ListViewItemDoubleClickCommandBehavior 如上图所示,这个
CommandBehavior
类将命令链接到控件
- 在上面的例子中,它是一个按钮库,但我们要制作一个ListViewItem
- 这一个需要prism,因为它继承的CommandBehaviorBase是该库的一部分。您可以全部获得(但对于本例,您只需要使用Prism.dll命令)
- 命名约定要求您应以以下格式命名此CommandBehavior
X—将命令绑定到的控件的名称(在本例中为ListViewItem)[X][Y]CommandBehavior
Y-用户执行的导致命令发生的操作(在本例中,双击)
public class ListViewItemDoubleClickCommandBehaviour : CommandBehaviorBase<ListViewItem>
{
public ListViewItemDoubleClickCommandBehaviour(ListViewItem controlToWhomWeBind)
: base(controlToWhomWeBind)
{
controlToWhomWeBind.MouseDoubleClick += OnDoubleClick;
}
private void OnDoubleClick(object sender, System.Windows.RoutedEventArgs e)
{
ExecuteCommand();
}
}
注:
我知道这看起来有很多复杂的代码,但是
public ICommand DisplaySelectedItemCmd { get; protected set; }
//This method goes in your constructor
private void InitializeCommands()
{
//Initializes the command
this.DisplaySelectedItemCmd = new RelayCommand(
(param) =>
{
this.DisplaySelectedItem((object)param);
},
(param) => { return this.CanDisplaySelectedItem; }
);
}
//The parameter should be your listview's selected item. I have no idea what type it is so I made it an object
public void DisplaySelectedPolicy(object selectedListViewItem)
{
//Code to perform when item is double clicked
}
private bool CanDisplaySelectedPolicy
{
get
{
return true; //Change this bool if you have any reason to disable the double clicking, as this bool basically is linked to the double click command firing.
}
}
xmlns:commands="clr-namespace:CommandHandling"
<Style TargetType="{x:Type ListViewItem}" x:Key="{x:Type ListViewItem}" >
<Setter Property="commands:DoubleClick.Command" Value="{Binding Path=bleh}"/>
</Style>
<ListView IsSynchronizedWithCurrentItem="True" Name="listView" Margin="32,158,66,0" VerticalAlignment="Top">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<EventSetter Event="PreviewMouseUp" Handler="itemClicked"></EventSetter>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
... etc
EventSetter ev = new EventSetter();
ev.Event = ListViewItem.PreviewMouseUpEvent;
ev.Handler = new MouseButtonEventHandler(itemClicked);
Style myStyle = new Style();
myStyle.TargetType = typeof(ListViewItem);
myStyle.Setters.Add(ev);
listView.ItemContainerStyle = myStyle;
void itemClicked(object sender, MouseButtonEventArgs e)
{
// item was licked in listview implement behavior in here
}