gpt4 book ai didi

c# - 在 ListBoxItem DataTemplate - WPF 内的嵌套控件中处理相同的单击事件

转载 作者:太空宇宙 更新时间:2023-11-03 12:04:26 25 4
gpt4 key购买 nike

当我们有一个自定义列表框时,它具有定义的鼠标左键单击事件处理,并且在 ListBoxItem 数据模板中还有一个额外的形状,当它被单击时需要执行一些操作,我们如何处理这些

我有一个自定义 ListBox 女巫试图处理 Click 事件:

在内容 View 中:

                <ABC:AListBox
ClickCommand="{Binding LaunchCommand}"
...>
</ABC:AListBox>

在它的数据模板中我们有这个:

        <DataTemplate x:Key="ThisListTemplate">
<StackPanel ...>
<Border Grid.Column="1" VerticalAlignment="Center">
<TextBlock
FontSize="15"
Foreground="White"
Text="{Binding Path=ItemTitle}" />
</Border>
<Canvas Height ="12" Width ="12" >
<Ellipse Name = "TheEllipse" Stroke="Black" Height ="12"
Width ="12" Cursor="Hand" Canvas.Left="185" Canvas.Top="12">
</Ellipse>
<Ellipse.InputBindings>
<MouseBinding Gesture="LeftClick"
Command="{Binding DataContext.LaunchFromXamlCommand , RelativeSource={RelativeSource AncestorType=ABC:AListBox}}"
CommandParameter="{Binding}" />
</Ellipse.InputBindings>
</Canvas>
</StackPanel>
</DataTemplate>

在作为我们数据上下文的 MVVM 中,我们有:

    public ICommand LaunchCommand { get; private set; }
public DelegateCommand<object> LaunchFromXamlCommand { get; private set; }

// Initialization on load:

this.LaunchCommand = new DelegateCommand(this.LaunchRun);
this.LaunchFromXamlCommand = new DelegateCommand<object>(this.LaunchFromXamlRun);


//---------
private void LaunchFromXamlRun(object param)
{
TheListItem app = (TheListItem)param;
...
}

private void LaunchRun()
{ ... }

在这里,除了通过模板调用的 LaunchFromXamlCommand 之外,我还使用了 2 个不同的命令 LaunchCommand 作为 ICommand。

LaunchFromXamlRun 将按预期正常触发。但也正如可以猜测的那样,将有 2 个引发的事件和 2 个命令被触发,我想省略一个并在该形状被击中时忽略一般的 ListBox 事件处理程序。

执行此操作的最佳解决方案是什么?

仅供引用: (可能不那么重要只是为了说明)该应用程序使用的是早期版本的 Prism(不要认为这在这里很重要)并且具有模块化代码,一切都在不同的程序集中分离,代码使用 MVVM 模式。

我希望我们有类似 e.handled = true 的机制,可以在给定场景中使用。

最佳答案

在您的列表框中使用该点击处理程序会加剧您的问题。我不知道你是怎么做到的,但这不能只是点击。这可能是 previewmousedown。因为,当然,作为选择项目的一部分,列表框会“吃掉”鼠标按下。

解决此问题的一种方法是不使用该列表框预览鼠标。在这里,我将我的行内容放在一个按钮中并绑定(bind)按钮的命令。当然,它看起来不像一个按钮。

我把圆圈做成一个按钮,并给它一个透明的填充,这样你就可以点击所有的按钮了。

    <ListBox ItemsSource="{Binding People}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding DataContext.ItemClickCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
CommandParameter="{Binding}"
>
<Button.Template>
<ControlTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LastName}"/>
<Button Command="{Binding DataContext.EllipseCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
>
<Button.Template>
<ControlTemplate>
<Ellipse Name = "TheEllipse" Stroke="Black"
Fill="Transparent"
Height ="12"
Width="12" Cursor="Hand">
</Ellipse>
</ControlTemplate>
</Button.Template>
</Button>

</StackPanel>
</ControlTemplate>
</Button.Template>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

我的 View 模型使用中继命令,但(显然)任何 ICommand 的实现都可以。我有上一个问题的人,我做了一些工作。

public class MainWindowViewModel : BaseViewModel
{
private RelayCommand ellipseCommand;
public RelayCommand EllipseCommand
{
get
{
return ellipseCommand
?? (ellipseCommand = new RelayCommand(
() =>
{
Console.WriteLine("CIRCLE clicked");
}
));
}
}
private RelayCommand<Person> itemClickCommand;
public RelayCommand<Person> ItemClickCommand
{
get
{
return itemClickCommand
?? (itemClickCommand = new RelayCommand<Person>(
(person) =>
{
Console.WriteLine($"You clicked {person.LastName}");
person.IsSelected = true;
}
));
}
}
private ObservableCollection<Person> people = new ObservableCollection<Person>();

public ObservableCollection<Person> People
{
get { return people; }
set { people = value; }
}

public ListCollectionView LCV { get; set; }
public MainWindowViewModel()
{
People.Add(new Person { FirstName = "Chesney", LastName = "Brown" });
People.Add(new Person { FirstName = "Gary", LastName = "Windass" });
People.Add(new Person { FirstName = "Liz", LastName = "McDonald" });
People.Add(new Person { FirstName = "Carla", LastName = "Connor" });
}
}

当您点击外部按钮时,它会捕获点击。这就是为什么我在命令中设置 IsSelected 以便通过绑定(bind)选择您单击的项目。

关于c# - 在 ListBoxItem DataTemplate - WPF 内的嵌套控件中处理相同的单击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55780718/

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