为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
繁花不似锦 2022-12-24 12:19:54
当我们有一个自定义列表框时,它为鼠标左键单击定义了事件处理,并且在 ListBoxItem 数据模板中还有一个附加形状,当它被单击时需要执行一些操作,我们如何处理这些我有一个 Custom ListBox 女巫试图处理 Click 事件:在内容视图中:                <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; }在这里,除了通过模板调用的 LaunchFromXamlCommand 之外,我还使用了 2 个不同的命令 LaunchCommand 作为 ICommand。LaunchFromXamlRun将按预期正常触发。但也正如可以猜测的那样,将有 2 个引发的事件和 2 个命令被触发,我想省略一个并在该形状被击中时忽略一般的 ListBox 事件处理程序。这样做的最佳解决方案是什么?仅供参考:( 可能不是那么重要只是为了说明)该应用程序正在使用早期版本的 Prism(不要认为这在这里很重要)并且具有模块化代码,所有内容都在不同的程序集中分离并且代码使用 MVVM 模式。我希望我们有e.handled = true一个可以在给定场景中使用的机制。
查看完整描述

1 回答

?
ITMISS

TA贡献1871条经验 获得超8个赞

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


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


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


    <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>

我的视图模型使用中继命令,但(显然)任何 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 以便通过绑定选择您单击的项目。


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 103 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号