【问题标题】:How to call Command from MVVM binding如何从 MVVM 绑定调用命令
【发布时间】:2014-05-25 11:45:28
【问题描述】:

我有下面的代码来使用 MVVM 绑定 ListBox 数据。我想从 MVVM 实现Command,数据已完全绑定,我不知道为什么它不适用于Command。单击按钮时我没有收到消息。

视图模型

public class BookmarkViewModel : INotifyPropertyChanged
    {
        public BookmarkViewModel()
        {
            DataSource ds = new DataSource();
            deleteBookmark = new Command(executeCommand) { Enabled = true };
            _bk = ds.getBookmarkDetail();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        List<BookmarkDetail> _bk;
        public List<BookmarkDetail> Bookmarks
        {
            get { return _bk; }
            set
            {
                if (_bk != value)
                {
                    _bk = value;
                    OnPropertyChanged("Bookmarks");
                }
            }
        }

        private Command deleteBookmark;
        public Command DeleteBookmark
        {
            get
            {
                return deleteBookmark;
            }
            set
            {
                deleteBookmark = value;
            }
        }

        void executeCommand()
        {
            System.Windows.MessageBox.Show(_bk[0].SuraName);
        }


        public class Command : ICommand
        {

            private readonly Action executeAction;

            private bool enabled;
            public bool Enabled
            {
                get
                {
                    return enabled;
                }
                set
                {
                    if (enabled != value)
                    {
                        enabled = value;

                        if (CanExecuteChanged != null)
                            CanExecuteChanged(this, new EventArgs());
                    }
                }
            }

            public Command(Action executeAction)
            {
                this.executeAction = executeAction;
            }

            public bool CanExecute(object parameter)
            {
                return enabled;
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                executeAction();
            }
        }
    }

和 XAML 绑定

<ListBox x:Name="lsbBookmarks" FontFamily="./Fonts/ScheherazadeRegOT.ttf#Scheherazade" 
                     FlowDirection="RightToLeft" 
                     Style="{StaticResource ListBoxStyle1}"  
                     ItemsSource="{Binding Bookmarks}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <StackPanel HorizontalAlignment="Stretch">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                    <ColumnDefinition Width="60"></ColumnDefinition>
                                </Grid.ColumnDefinitions>
                                <StackPanel Orientation="Horizontal" Grid.Column="0"
                                                HorizontalAlignment="Stretch">
                                    <TextBlock Padding="20,0,10,0" HorizontalAlignment="Stretch">
                                                    <Run FontSize="50" Text="{Binding ArabicText.ArabicAyaNumber}"  
                                                         FontFamily="./Fonts/KPGQPC.otf#KFGQPC Uthmanic Script HAFS" 
                                                         Foreground="Blue"/> <Run FontSize="30" Text="{Binding ArabicText.Aya}"/>
                                    </TextBlock>
                                </StackPanel>
                                <Button Grid.Column="1" Tag="{Binding ArabicText.ArabicTextID}" 
                                                    VerticalAlignment="Center"
                                                    Height="60" Width="50" HorizontalAlignment="Right" 
                                                            Content="X" BorderBrush="Red" 
                                                            Background="Red" BorderThickness="0" 
                                                    Padding="0" Command="{Binding DeleteBookmark}"></Button>
                            </Grid>
                            <Line X1="0" X2="1" Y1="0" Y2="0" Stretch="Fill" VerticalAlignment="Bottom" 
                                                            StrokeThickness="1" Stroke="LightGray" />
                        </StackPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

任何想法,如何使用 MVVM 实现Command

谢谢!

【问题讨论】:

    标签: c# windows-phone-8


    【解决方案1】:

    如果我是你,我会:

    1. 将 Command 实现移动到单独的文件中在 BookmarkViewModel 类的范围之外声明它。
    2. 按照 ig2r 的建议使用第二个选项。您的绑定将如下所示:Command="{Binding DataContext.DeleteBookmark, ElementName=lsbBookmarks}" 您还可以使用除 lsbBookmarks 之外的任何其他 ElementName,它被定义为 ListBox 的父级。

    【讨论】:

    • 非常感谢,两者都为我工作。我会将@igr2 的答案标记为他之前回答的解决方案。再次感谢!
    【解决方案2】:

    您的DeleteBookmark 命令似乎作为BookmarkViewModel 类的属性公开,而DataTemplate 中用于呈现各个ListBox 项的实际数据上下文将是BookmarkDetail 的实例。由于BookmarkDetail 没有声明DeleteBookmark 命令,所以绑定失败。

    要更正此问题,可以:

    1. BookmarkDetail 类上定义并公开DeleteBookmark 命令,或者
    2. 扩展您的命令绑定以告诉绑定系统在哪里查找删除命令,例如,Command="{Binding DataContext.DeleteBookmark, ElementName=lsbBookmarks}"(未经测试)。

    【讨论】:

    • 非常感谢,辛苦了!
    • 你也可以给我打电话,我怎样才能将参数传递给函数?
    • 在第二种情况下传递参数,可以使用按钮上的CommandParameter属性,并将其绑定到调用它的元素,即当前项的DataContext . CommandParameter="{Binding}" 应该足够了。
    • 谢谢,想通了。
    猜你喜欢
    • 2010-12-23
    • 2020-03-10
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 2014-12-20
    • 2011-07-29
    • 1970-01-01
    相关资源
    最近更新 更多