我将以下数据模板应用于ListBox:
<DataTemplate x:Key="MyTemplate" DataType="{x:Type DAL:Person}">
<StackPanel Orientation="Horizontal">
<Button Content="X" Command="{x:Static cmd:MyCommands.Remove}"/>
<TextBlock Text="{Binding Person.FullName}" />
</StackPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
当我单击按钮时,命令被触发但ListBoxItem未被选中.如何强制它被选中,以便我可以在"执行"方法中获取所选项目?
谢谢
Ale*_*ven 11
一个更好的方法,因为你真的不想选择项目(因为它会很快被删除)将把项目本身作为CommandParameter传递给Command.
或者,您可以使用代码隐藏或使用触发器以迂回方式进行,但我认为不会如此.例如:
你可以处理列表框上的ButtonBase.Click事件,比如
<ListBox ButtonBase.Click="lb_Click"
...
Run Code Online (Sandbox Code Playgroud)
然后在你的代码后面,这样做:
private void lb_Click(object sender, RoutedEventArgs e)
{
object clicked = (e.OriginalSource as FrameworkElement).DataContext;
var lbi = lb.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
lbi.IsSelected = true;
}
Run Code Online (Sandbox Code Playgroud)
获取单击的绑定项,因为按钮的datacontext是从其模板化项继承的,然后是ListBox的ItemContainerGenerator中的实际自动生成的ListBoxItem,并将IsSelected属性设置为true.我认为这是最快捷,最简单的方法之一.也适用于模板中的多个ButtonBase派生对象.
当然,您还可以更好地将所有这些(或多或少完全相同)封装为可重用行为:
public class SelectItemOnButtonClick : Behavior<ListBox>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler), true);
}
protected override void OnDetaching()
{
this.AssociatedObject.RemoveHandler(ButtonBase.ClickEvent, new RoutedEventHandler(handler));
base.OnDetaching();
}
private void handler(object s, RoutedEventArgs e)
{
object clicked = (e.OriginalSource as FrameworkElement).DataContext;
var lbi = AssociatedObject.ItemContainerGenerator.ContainerFromItem(clicked) as ListBoxItem;
lbi.IsSelected = true;
}
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它:
<ListBox xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" ...>
<i:Interaction.Behaviors>
<local:SelectItemOnButtonClick />
</i:Interaction.Behaviors>
</ListBox>
Run Code Online (Sandbox Code Playgroud)
添加错误处理代码,如至少是null检查,当然 - 不希望像这样轰炸你的应用程序这样简单的事情.
要理解该问题,该按钮会将处理它的所有鼠标事件(MouseDown/Click)的Handled属性设置为true,以便ListBoxItem不会考虑它们.你也可以将MouseDown事件附加到ListBox并向上走可视树,直到你到达父ListBoxItem,但这更棘手......呃,如果你很好奇,你可以阅读这篇文章,知道为什么,基本上你' ll还会遇到FrameworkContentElements(它也会响应MouseDown),因此代码会变得更复杂,而且在datatemplate内部点击的任何东西都会触发ListBoxItem被选中,无论它是否将事件标记为已处理.
嘿,我也尝试用风格和触发器专门做它,但它快速变得丑陋,我失去了兴趣(并且失去了所有......错误的东西).基本上它可以解决,我想,但我认为这不值得打扰.也许我忽略了一些显而易见的事情,不知道.
| 归档时间: |
|
| 查看次数: |
5699 次 |
| 最近记录: |