【问题标题】:uwp gridview delete item with button within datatemplateuwp gridview删除数据模板中带有按钮的项目
【发布时间】:2017-05-07 10:31:53
【问题描述】:

我在 UWP 应用程序中有一个 gridview,并且我在 datatemplate 的每个 gridview 项目中都放置了一个 按钮,以便它可以用于delete/remove 从 gridview 中删除该特定项目(从后面的 observableCollection 中删除它)。我没有使用 MVVM 方法,因为我不太熟悉它,我使用普通的 Observable Collection 来绑定数据和数据模板。

如果你能建议我一个更好的方法,请使用 MVVM 建议我如何去做。 提前致谢

代码:

XAML GRID VIEW(带有红色背景的按钮是我想用来删除项目的按钮)

<controls:AdaptiveGridView Name="HistoryGridView" StretchContentForSingleRow="False"
                           Style="{StaticResource MainGridView}"
                           ItemClick ="HistoryGridView_SelectionChanged"
                           ItemsSource="{x:Bind HistoryVideos, Mode=OneWay}">
    <controls:AdaptiveGridView.ItemTemplate>
        <DataTemplate  x:DataType="data:Video">
            <StackPanel Margin="4" >
                <Grid>
                    <Button  Background="Red"
                            HorizontalAlignment="Right" VerticalAlignment="Top"
                            Height="36" Canvas.ZIndex="1"
                            Style="{StaticResource TransparentButton}" Width="36">
                        <fa:FontAwesome Icon="Close" FontSize="20" HorizontalAlignment="Center" Foreground="White"
                                            />
                    </Button>
                    <Image  Canvas.ZIndex="0"    Source="{x:Bind Thumbnail}" Style="{StaticResource GridViewImage}"/>
                    <Border Style="{StaticResource TimeBorder}" Height="Auto" VerticalAlignment="Bottom"
                            Canvas.ZIndex="1"
                            HorizontalAlignment="Left">
                        <TextBlock Text="{x:Bind Duration}" Foreground="White" Height="Auto"/>
                    </Border>
                </Grid>
                <TextBlock Text="{x:Bind Name}"  Style="{StaticResource GridViewVideoName}"/>
                <TextBlock Text="{x:Bind ParentName}"  Style="{StaticResource GridViewParentName}"/>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
                    <TextBlock Text="{x:Bind Views}" Style="{StaticResource GridViewViews}"/>
                    <TextBlock Text="Views" HorizontalAlignment="Right"/>
                </StackPanel>
            </StackPanel>

        </DataTemplate>
    </controls:AdaptiveGridView.ItemTemplate>
</controls:AdaptiveGridView>

代码背后

public History()
{
    this.InitializeComponent();
    HistoryVideos = new ObservableCollection<Video>();
}

public ObservableCollection<Video> HistoryVideos { get; private set; }

我正在使用 onnavigated to 方法来填充集合,它工作正常,而且我想这与这里无关。

【问题讨论】:

    标签: c# xaml gridview mvvm uwp-xaml


    【解决方案1】:

    我们可以将Command 添加到Button 以在按下此按钮时调用,我们可以使用参数传递给Command 属性。

    要使用命令,我们应该能够定义一个继承自ICommandDelegateCommand 类。

    例如:

    internal class DelegateCommand : ICommand
    {
        private Action<object> execute;
        private Func<object, bool> canExecute;
    
        public DelegateCommand(Action<object> execute)
        {
            this.execute = execute;
            this.canExecute = (x) => { return true; };
        }
    
        public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }
    
        public bool CanExecute(object parameter)
        {
            return canExecute(parameter);
        }
    
        public event EventHandler CanExecuteChanged;
    
        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
            {
                CanExecuteChanged(this, EventArgs.Empty);
            }
        }
    
        public void Execute(object parameter)
        {
            execute(parameter);
        }
    }
    

    我们可以在Video 中添加Id 属性,然后我们可以将Id 属性传递给CommandParameter。当我们点击Button 时,ExecuteDeleteCommand 方法将被触发。我们可以使用IdHistoryVideos中找到Video,并使用Remove方法将其删除。

    ViewModel代码:

    internal class ViewModel
    {
        private ObservableCollection<Viedo> _videos;
    
        public ObservableCollection<Viedo> Videos
        {
            get
            {
                return _videos;
            }
            set
            {
                if (_videos != value)
                {
                    _videos = value;
                }
            }
        }
    
        public ICommand DeleteCommand { set; get; }
    
        private void ExecuteDeleteCommand(object param)
        {
            int id = (Int32)param;
            Viedo cus = GetCustomerById(id);
    
            if (cus != null)
            {
                Videos.Remove(cus);
            }
        }
    
        private Viedo GetCustomerById(int id)
        {
            try
            {
                return Videos.First(x => x.Id == id);
            }
            catch
            {
                return null;
            }
        }
    
        public ViewModel()
        {
            Videos = new ObservableCollection<Viedo>();
            for (int i = 0; i < 5; i++)
            {
                Videos.Add(new Viedo());
                Videos[i].Name = "Name";
                Videos[i].Id = i;
            }
    
            this.DeleteCommand = new DelegateCommand(ExecuteDeleteCommand);
        }
    }
    

    XAML 代码:

    <GridView Name="MyGridView"  ItemsSource="{Binding Videos}">
        <GridView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Name}"></TextBlock>
                    <Button  Background="Red"
                        HorizontalAlignment="Right" VerticalAlignment="Top"
                        Height="36" Canvas.ZIndex="1"
                    Width="36"  Command="{Binding DataContext.DeleteCommand, ElementName=MyGridView}" CommandParameter="{Binding Id}">
                    </Button>
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
    

    背后的代码:

    private ViewModel myViewModel;
    
    public MainPage()
    {
        this.InitializeComponent();
        myViewModel = new ViewModel();
        MyGridView.DataContext = myViewModel;
    }
    

    更新:

    <GridView Name="MyGridView"  ItemsSource="{x:Bind myViewModel.Videos}">
        <GridView.ItemTemplate>
            <DataTemplate x:DataType="local:Viedo">
                <StackPanel>
                    <TextBlock Text="{x:Bind Name}"></TextBlock>
                    <Button  Background="Red"
                        HorizontalAlignment="Right" VerticalAlignment="Top"
                        Height="36" Canvas.ZIndex="1"
                    Width="36"  Command="{Binding DataContext.DeleteCommand, ElementName=MyGridView}" CommandParameter="{Binding Id}">
                    </Button>
                </StackPanel>
            </DataTemplate>
        </GridView.ItemTemplate>
    </GridView>
    

    【讨论】:

    • 请问我们为什么要使用 Inotifyproeprtty changed 。 Observable Collection 不是已经内置了该功能吗?
    • @touseef 是的,你是对的,我已经更新了答案。 ObservableCollection 在添加、删除项目或刷新整个列表时提供通知。
    • thnku,它看起来是一个很好的答案。但我一直在研究,我想它也可以用 x:Bind 来完成,性能更高。在那种情况下我们也不需要 ICommand 实现吗?那正确吗?如果是这样,您能否建议以这种方式实施? :)
    • 我的解决方案是使用 MVVM 方法,我们也可以使用 x:bind。如果我们使用CommandCommandParameter,我们需要ICommand 实现。由于DeleteCommand 不在Video 类中,所以我们不能对ButtonCommand 使用x:bind。如果要使用,应该可以在Video类中设置DeleteCommand
    猜你喜欢
    • 2015-07-30
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2015-03-26
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    相关资源
    最近更新 更多