从 ListViewItem 单击 UWP 按钮

Posted

技术标签:

【中文标题】从 ListViewItem 单击 UWP 按钮【英文标题】:UWP Button click from ListViewItem 【发布时间】:2020-07-06 02:41:09 【问题描述】:

真心希望有经验的大侠指点一下。

我为 UWP 项目设置了以下设置:

ListView 在我的应用程序页面内的 XAML 中声明,Tubes.xaml

<ListView Name="TubesGrid"
              ItemsSource="x:Bind TubeItems, Mode=TwoWay"
              ItemTemplateSelector="StaticResource TubeTemplateSelector"
              IsItemClickEnabled="True"
              ItemClick="TubesGrid_ItemClick"
              SelectionChanged="TubesGrid_SelectionChanged">

UserControl 作为ListViewItem (UserControl.Resources) 的模板:

<local:TubeTemplateSelector x:Key="TubeTemplateSelector"
                            TubeTemplate="StaticResource TubeTemplate">
</local:TubeTemplateSelector>
<DataTemplate x:Key="TubeTemplate" x:DataType="data:Tube">
    <local:TubeTemplate HorizontalAlignment="Stretch" VerticalAlignment="Stretch" FavoritesNumber="x:Bind SpaceLength, Mode=OneWay"></local:TubeTemplate>
</DataTemplate> 

TubeTemplate 里面我有一个按钮,在其他视图旁边:

<Button Name="RemoveTube"
        Click="RemoveTube_Click"
    <Image
            Source="../Assets/xIcon.png"
            Stretch="None">
    </Image>
</Button>

我想要达到的目标:

    当我单击ListViewItem 时,我希望触发ItemClick 事件。这行得通。 但是,当我单击 ListViewItem 内的按钮时,我希望在主页内触发不同的事件。

这个想法是点击一个项目来选择它,但是当我点击项目内的按钮时,我希望删除该项目。

我有什么选择?

【问题讨论】:

【参考方案1】:

如果看起来是在不使用视图模型的情况下执行此操作,那么您可以向 TubeTemplate 控件添加一个事件。

 public event EventHandler Closed;

当点击关闭按钮时,您将触发该事件。

private void RemoveTube_Click(object sender, RoutedEventArgs e)

    Closed?.Invoke(this, EventArgs.Empty); // Even better would be to give the item clicked (the data context)

然后,您可以在 MainPage 中订阅该事件。

<local:TubeTemplate HorizontalAlignment="Stretch" 
                    VerticalAlignment="Stretch" 
                    Closed="TubeTemplate_Closed">

</local:TubeTemplate>

TubeTemplate_Closed 方法中,您可以删除点击的项目。

private void TubeTemplate_Closed(object sender, EventArgs e)

    var element = (FrameworkElement)sender;
    var tube = (Tube)element.DataContext;

    TubeItems.Remove(tube);

【讨论】:

【参考方案2】:

想法是点击一个项目来选择它,但是当我点击项目内的按钮时,我希望删除该项目。

比较好的方法是把按钮命令属性和MainPage命令方法绑定,并在后面的代码中处理数据源。您可以参考以下代码。

代码背后

public sealed partial class MainPage : Page

    public MainPage()
    
        MakeDataSource();
        this.InitializeComponent();
        DataContext = this;

    
    public ObservableCollection<string> Items  get; set; 

    private void MakeDataSource()
    
        Items = new ObservableCollection<string>()  "Nico","CCor","Jack";

    
    public ICommand BtnCommand
    
        get
        
            return new CommadEventHandler<object>((s) => BtnClick(s));
        
    

    private void BtnClick(object s)
    
        Items.Remove(s as string);
    

public class CommadEventHandler<T> : ICommand

    public event EventHandler CanExecuteChanged;

    public Action<T> action;
    public bool CanExecute(object parameter)
    
        return true;
    

    public void Execute(object parameter)
    
        this.action((T)parameter);
    
    public CommadEventHandler(Action<T> action)
    
        this.action = action;

    

Xaml 代码

请注意,我们需要将当前焦点列表视图项参数传递给命令方法并将其从数据源中删除。

<Grid HorizontalAlignment="Stretch" x:Name="RootGrid">
    <ListView ItemsSource="Binding Items" x:Name="MyListView">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="VerticalContentAlignment" Value="Stretch"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid  HorizontalAlignment="Stretch">
                    <TextBlock Text="Binding" VerticalAlignment="Center"/>
                    <Button HorizontalAlignment="Right" 
                            Margin="0,0,30,0" 
                            Content="Favorite" 
                            Command="Binding ElementName=MyListView,Path=DataContext.BtnCommand" 
                            CommandParameter="Binding"/>
                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

【讨论】:

感谢您的宝贵时间。我现在要试试这个解决方案。

以上是关于从 ListViewItem 单击 UWP 按钮的主要内容,如果未能解决你的问题,请参考以下文章

单击ListViewItem时如何将焦点设置在TextBox上?

UWP重写Frame.Navigate将数据从ListViewItem传递到新的页面casues Null Exception

C# Wpf 如何使用其中的按钮更改 Listviewitem 的高度?

如何为 UWP 调整 Telerik UI 的 listviewitem 容器的高度

如何在按钮单击时关闭 uwp 中的吐司

禁用UWP ListView控件的ListViewItem显示效果