如何从MVVM绑定调用Command

时间:2014-05-25 11:45:28

标签: c# windows-phone-8

我有以下代码使用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

谢谢!

2 个答案:

答案 0 :(得分:1)

如果我是你,我会:

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

答案 1 :(得分:0)

您的DeleteBookmark命令似乎作为BookmarkViewModel类的属性公开,而用于呈现单个ListBox项的DataTemplate内的实际数据上下文将是BookmarkDetail。由于BookmarkDetail未声明DeleteBookmark命令,因此绑定失败。

要纠正此问题,请执行以下操作:

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