2017-08-07 39 views
2

我想製作一個HamburgerMenu.and這裏是XAML。如何在UWP的ItemsControl中綁定click事件?

<SplitView Grid.Row="1" HorizontalAlignment="Left"> 
       <SplitView.Content> 
        <ListView> 
         <ItemsControl x:Name="NavItemsControl"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <StackPanel></StackPanel> 
           </ItemsPanelTemplate> 
          </ItemsControl.ItemsPanel> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 
            <Button> 
             <Grid> 
              <Grid.ColumnDefinitions> 
               <ColumnDefinition Width="auto"></ColumnDefinition> 
               <ColumnDefinition Width="*"></ColumnDefinition> 
              </Grid.ColumnDefinitions> 
              <TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}"></TextBlock> 
              <TextBlock Text="{Binding Content}" Grid.Column="1"></TextBlock> 
             </Grid> 
            </Button> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 
        </ListView> 
       </SplitView.Content> 
      </SplitView> 

這裏是後面的代碼:

public class NavItems : INotifyPropertyChanged 
    { 
     string _Icon; 
     public string Icon 
     { 
      set 
      { 
       _Icon = value; 
       OnPropertyChanged("Icon"); 
      } 
      get 
      { 
       return _Icon; 
      } 
     } 
     string _Content; 
     public string Content 
     { 
      set 
      { 
       _Content = value; 
       OnPropertyChanged("Content"); 

      } 
      get 
      { 
       return _Content; 
      } 
     }    

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

設置好的NavItemsControl的的ItemSource,我可以在酒店輕鬆綁定,如圖標或Content.The後唯一的問題是我想click事件綁定的 按鈕,但我不知道如何綁定它。

我嘗試使用委託綁定單擊事件,但它沒有用,並報告錯誤。

你能幫我嗎?

謝謝

回答

4

在我們開始之前你的問題,讓我們先解決您的XAML。您正在使用ListView來包裝ItemsControl,這是不必要的。實際上,ListView本身繼承自ItemsControl,基本上它是一個更強大的版本。在你的情況下,一個ItemsControl應該是足夠的,所以你可以安全地刪除ListView包裝。

既然你已經使用了Button你的模板裏面,你可以創建一個ClickCommand(類型ICommand)在NavItemsButtonCommand屬性綁定到它。

<Button Command="{Binding ClickCommand}" /> 

有噸在互聯網上的資源,你可以找到一個ICommand實現的,看看它是如何在UWP Toolkit完成。


旁註

我個人不喜歡使用SelectionChanged因爲它是一個數據驅動事件,可以通過數據的變化來觸發。這可能是不可預測的並且容易出錯。此外,除非您手動重置SelectedIndex,否則無法重新選擇相同的項目。一個按鈕Click(或ItemClickListView)是一個輸入驅動的事件,它只能(在大多數情況下)由用戶操作調用,很少會給你帶來任何副作用。

+1

謝謝!這很有幫助.. – Pratyay

+1

我是UWP的開端,非常感謝您對Listview的建議。更重要的是,我同意您對SelectionChanged的看法。謝謝。 –

1

爲了爲您註冊一個事件按鈕單擊您需要添加和定義ListView的Selection Changed事件。所以,你的代碼應該是這樣的:

<SplitView Grid.Row="1" HorizontalAlignment="Left"> 
       <SplitView.Content> 
        <ListView x:Name="itemListView" SelectionChanged="ItemListView_SelectionChanged"> 
         <ItemsControl x:Name="NavItemsControl"> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <StackPanel></StackPanel> 
           </ItemsPanelTemplate> 
          </ItemsControl.ItemsPanel> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 
            <Button> 
             <Grid> 
              <Grid.ColumnDefinitions> 
               <ColumnDefinition Width="auto"></ColumnDefinition> 
               <ColumnDefinition Width="*"></ColumnDefinition> 
              </Grid.ColumnDefinitions> 
              <TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}"></TextBlock> 
              <TextBlock Text="{Binding Content}" Grid.Column="1"></TextBlock> 
             </Grid> 
            </Button> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
         </ItemsControl> 
        </ListView> 
       </SplitView.Content> 
      </SplitView> 

C#代碼隱藏應該是這個樣子:

private void ItemListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
     if(itemListView.SelectedItem!=null){ 
     Debug.WriteLine(itemListView.SelectedIndex + " Index selected"); 
     // More logic here 
     } 

} 
0

我試圖用ICommand來做,但代碼看起來很喜歡這麼醜。僅供參考。背後

<SplitView Grid.Row="1" HorizontalAlignment="Left"> 
       <SplitView.Content> 
        <ItemsControl x:Name="NavItemsControl"> 
         <ItemsControl.ItemsPanel> 
          <ItemsPanelTemplate> 
           <StackPanel></StackPanel> 
          </ItemsPanelTemplate> 
         </ItemsControl.ItemsPanel> 
         <ItemsControl.ItemTemplate> 
          <DataTemplate> 
           <Button Command="{Binding ClickCommand}" Padding="10,20" Background="Transparent"> 
            <Grid> 
             <Grid.ColumnDefinitions> 
              <ColumnDefinition Width="auto"></ColumnDefinition> 
              <ColumnDefinition Width="*"></ColumnDefinition> 
             </Grid.ColumnDefinitions> 
             <TextBlock FontFamily="Segoe MDL2 Assets" Text="{Binding Icon}" VerticalAlignment="Center"></TextBlock> 
             <TextBlock Text="{Binding Content}" Grid.Column="1" VerticalAlignment="Center" Padding="20,0,0,0"></TextBlock> 
            </Grid> 
           </Button> 
          </DataTemplate> 
         </ItemsControl.ItemTemplate> 
        </ItemsControl> 
       </SplitView.Content> 
      </SplitView> 

代碼:

public MainPage() 
     { 
      InitializeComponent(); 
      NavItems.ClickVoidDelegate CD = new NavItems.ClickVoidDelegate(()=> { Debug.WriteLine("123"); }); 
      List<NavItems> NavItemsList = new List<NavItems>() 
      { 
       new NavItems(){ 
        Icon="\xE166",Content="Open",ClickCommand=new NavItems.ClickCommandClass(CD) 
       } 
      }; 

      NavItemsControl.ItemsSource = NavItemsList; 
     } 
public class NavItems : INotifyPropertyChanged 
     { 
      string _Icon; 
      public string Icon 
      { 
       set 
       { 
        _Icon = value; 
        OnPropertyChanged("Icon"); 

       } 
       get 
       { 
        return _Icon; 
       } 
      } 
      string _Content; 
      public string Content 
      { 
       set 
       { 
        _Content = value; 
        OnPropertyChanged("Content"); 

       } 
       get 
       { 
        return _Content; 
       } 
      } 
      ClickCommandClass _ClickCommand; 
      public ClickCommandClass ClickCommand 
      { 
       get; 
       set; 
      } 
      public class ClickCommandClass : ICommand 
      { 
       public ClickCommandClass(ClickVoidDelegate ClickVoid) 
       { 
        _ClickVoid = ClickVoid; 
       } 
       ClickVoidDelegate _ClickVoid; 
       public void Execute(object parameter) 
       { 
        if (_ClickVoid != null) 
        { 
         _ClickVoid(); 
        } 
       } 
       public bool CanExecute(object parameter) 
       { 
        return true; 
       } 
       public event EventHandler CanExecuteChanged; 
      } 
      public delegate void ClickVoidDelegate(); 
      protected virtual void OnPropertyChanged(string propertyName) 
      { 
       PropertyChangedEventHandler handler = PropertyChanged; 
       if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
      } 
      public event PropertyChangedEventHandler PropertyChanged; 
     } 
相關問題