UWP - MVVM - 使用ItemTemplate按钮删除ListView项

时间:2018-04-30 20:54:23

标签: c# listview mvvm uwp listviewitem

我有一个显示项目列表的屏幕,用户可以点击按钮从列表中删除相应的项目。

我正在尝试使用MVVM。

但该项在获取操作时不知道包含列表。 我在这里和那里看到了一些答案,但是没有一个使用我在我的环境中开箱即用的MVVM功能 例如,那个使用PRISM的人(不知道我是否也应该使用它,它是标准的吗?):

这是XAML:

<ListView ItemsSource="{Binding MyItemList}" SelectionMode="None" ScrollViewer.VerticalScrollMode="Disabled" ItemContainerTransitions="{x:Null}"> 
    <ListView.ItemTemplate>
        <DataTemplate >
            <Grid Grid.Row="1" HorizontalAlignment="Stretch" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*" />
                    <ColumnDefinition Width="2*" />
                </Grid.ColumnDefinitions>
                <TextBox Grid.Column="0" Text="{Binding ItemClass.Property01, Mode=TwoWay}" />
                <Button Grid.Column="1" Command="{Binding RemoveItemCommand}" >
                    <SymbolIcon Symbol="Cancel" />
                </Button>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这是ModelView列表:

private static ObservableCollection<ItemClass> _MyItemList = new ObservableCollection<ItemClass> {
    new ItemClass{ Property01 = "Sometext" }
};
public ObservableCollection<ItemClass> MyItemList { get { return _MyItemList; } }

我希望能够执行以下操作(主模型视图中的代码示例,如果需要解决,我可以创建项目模型视图):

public IMvxCommand RemoveItemCommand { get; private set; }
public MyViewModel(IUserDialogs dialogs)
{
    RemoveItemCommand = new MvxCommand(RemoveItem);
}
public void RemoveItem(object theItem) { MyItemList.Remove(theItem); }

3 个答案:

答案 0 :(得分:1)

x:Name="listView"属性添加到ListView,然后添加到模板

<Button Grid.Column="1"
    Command="{Binding ElementName=listView, Path=DataContext.RemoveItemCommand}"
    CommandParameter="{Binding}" >

但是,当我遇到这样的问题时,我通常只会使用代码。原因是,我可以在visual studio中使用调试器来处理C#代码,但调试这些复杂的绑定要困难得多。这是一个C#版本,代码是IMO清洁,更容易调试:

void removeItem_Click( object sender, RoutedEventArgs e )
{
    object i = ((FrameworkElement)sender).DataContext;
    ( this.DataContext as MyViewModel )?.RemoveItem( i );
}

或许这只是我个人的偏好。

答案 1 :(得分:0)

最好在列表视图上有一个上下文菜单项(或某个页面上的删除按钮)来删除当前选定的项目。然后,您可以从列表视图中获取选择。

或者,您可以将上下文菜单附加到PrepareContainterForItemOverride中的列表视图项(并在另一个Override方法中将其分离)

这将是一种更标准的交互方式。

如果你必须在列表视图项中有按钮,那么获取列表项的最简单方法可能是使用可视化树帮助器从按钮上升到列表视图项,然后获取实际项从列表视图项。

答案 2 :(得分:0)

感谢所有提示, 使用Soonts答案,我能够开发出快速解决方案,

以下是最终实现的内容,以供任何想要复制/粘贴/适应的人参考(注意我没有测试代码,因为我替换了变量/函数名称):

XAML:

<ListView x:Name="ItemClass_ListView" ItemsSource="{Binding MyItemList}" SelectionMode="None" ScrollViewer.VerticalScrollMode="Disabled" ItemContainerTransitions="{x:Null}"> 
    <ListView.ItemTemplate>
        <DataTemplate >
            <Grid Grid.Row="1" HorizontalAlignment="Stretch" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="2*" />
                    <ColumnDefinition Width="2*" />
                </Grid.ColumnDefinitions>
                <TextBox Grid.Column="0" Text="{Binding ItemClass.Property01, Mode=TwoWay}" />
                <Button Grid.Column="1" Command="{Binding ElementName=ItemClass_ListView, Path=DataContext.RemoveItemCommand}" CommandParameter="{Binding}" >
                    <SymbolIcon Symbol="Cancel" />
                </Button>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

视图模型:

public class MyViewModel : BaseViewModel, INotifyPropertyChanged
{
    public IMvxCommand RemoveItemCommand { get; private set; }
    public MyViewModel()
    {
        // Initializing Commands
        RemoveItemCommand = new MvxCommand<ItemClass>(OnRemoveItemClick);
    }

    public void OnRemoveItemClick(ItemClass anItem)
    {
        // Do stuff...
    }

    private static ObservableCollection<ItemClass> _MyItemList = new ObservableCollection<ItemClass> {
        new ItemClass(),
        new ItemClass()
    };

    public ObservableCollection<ItemClass> MyItemList
    {
        get { return _MyItemList; }
    }
}