2014-05-25 7 views
0

MVVM을 사용하여 ListBox 데이터를 바인딩하는 코드는 다음과 같습니다. MVVM에서 Command을 함축하고 싶습니다. 데이터가 완전히 바인드되어 있는데 왜 Command과 작동하지 않는지 알 수 없습니다. 버튼을 클릭 할 때 메시지를받지 못합니다.MVVM에서 명령을 호출하는 방법

<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> 

어떤 아이디어를 결합

뷰 모델

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, 어떻게 MVVM을 사용하여 Command를 구현하는 방법?

감사합니다.

답변

0

개별 목록 상자 항목을 렌더링하는 데 사용되는 DataTemplate 내에서 실제 데이터 컨텍스트가 BookmarkDetail의 인스턴스가 될 것입니다 반면에 당신의 DeleteBookmark 명령의 BookmarkViewModel 클래스의 속성으로 노출 된 것 같습니다. BookmarkDetailDeleteBookmark 명령을 선언하지 않으므로 바인딩이 실패합니다. 예를 들면, 여기서 삭제 명령을 찾기 위해 바인딩 시스템에 알릴 수 있도록 바인딩 명령을 확장

  1. 정의하고 BookmarkDetail 클래스에 DeleteBookmark 명령을 노출, 또는
  2. :

    는이 문제를 해결하려면 다음 중 하나를 Command="{Binding DataContext.DeleteBookmark, ElementName=lsbBookmarks}" (테스트되지 않음).

+0

감사합니다. Worked! – ARH

+0

당신은 또한 제게 전화를주십시오, 어떻게 함수에 param을 전달할 수 있습니까? – ARH

+0

두 번째 시나리오에서 매개 변수를 전달하려면 단추의'CommandParameter' 속성을 사용하여 호출하는 요소, 즉 현재 항목의 DataContext에 바인딩합니다. 'CommandParameter = "{Binding}"'충분해야합니다. – ig2r

1

나는 것 당신이라면 :

  1. 이동은 별도의 파일에 명령 구현이 또는이 BookmarkViewModel 클래스의 범위를 벗어난를 선언합니다.
  2. ig2r suggest로 두 번째 옵션을 사용하십시오. 귀하의 바인딩은 다음과 같습니다 : Command="{Binding DataContext.DeleteBookmark, ElementName=lsbBookmarks}" ListBox의 부모로 정의 된 lsbBookmarks 이외의 다른 ElementName을 사용할 수도 있습니다.
+0

고마워, 둘 다 나를 위해 일했다. 그는 @ igr2 대답을 해결책으로 표시 할 것입니다. 다시 한번 감사드립니다! – ARH

관련 문제