繁体   English   中英

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

[英]Handling the same click event in a nested control inside ListBoxItem DataTemplate - WPF

当我们有一个自定义列表框,定义了鼠标左键单击的事件处理,还有 ListBoxItem 数据模板中的一个附加形状,当它被点击时需要做一些动作,我们如何处理这些

我有一个自定义列表框女巫试图处理 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; }

    // 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。 因为,当然,列表框“吃掉”鼠标作为选择项目的一部分。

解决此问题的一种方法是不使用该列表框 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 以便您单击的项目通过绑定被选中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM