2015-04-17 47 views
2

我有一個帶有多個項目的ListView。 ListViewItems是一個模板,其中包含有關ObservableCollection和Button中項目的詳細信息。根據ListView中的位置觸發按鈕的可見性

我的目標是讓按鈕只在最後一個ListViewItem上可見。爲此,我實現了一個轉換器並將其綁定到Button的可見性,該可見性檢查ListViewItem的索引與ListView的計數並返回Visibility.Visible或Visibility.Collapsed。

這工作正常,當頁面第一次加載,但是當我添加額外的項目到ListView,它不會更新現有的ListViewItems,它只運行新的項目的轉換器。

是否有一個很好的xaml(MVVM友好)的方式來觸發它來運行綁定?

我的XAML:

 <ListView x:Name="lstBox" ItemsSource="{Binding People}" Background="Yellow" > 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <WrapPanel> 
        <TextBlock Text="{Binding Firstname}" /> 
        <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, Path=DataContext.AddPersonCommand}" Content="Add Person" Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Converter={StaticResource IsLastItemToVisibilityConverter}}" /> 
       </WrapPanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

我的轉換器:

public class IsLastItemToVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     ListViewItem item = value as ListViewItem; 
     ListView ListView = ItemsControl.ItemsControlFromItemContainer(item) as ListView; 
     int index = ListView.ItemContainerGenerator.IndexFromContainer(item); 
     if (index == ListView.Items.Count - 1) 
     { 
      return Visibility.Visible; 
     } 
     else 
     { 
      return Visibility.Collapsed; 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

爲什麼不把一個按鈕放在列表視圖(在最後一項可能),而不是? –

+0

我相信你必須實現'ConvertBack'並將綁定模式設置爲'TwoWay' – Ninglin

+0

單個按鈕將是我的首選解決方案,但我給出的要求是這樣做。 –

回答

0

ObservableCollection應該包含(無論你怎麼稱呼它像人或)一個視圖模型類型的項目。該視圖模型應包含每個項目按鈕的Visibility值,並將您的轉換器更改爲BoolToVisibilityConverter

在這種溶劑中,您只需在更改集合時更新項目的可見性。你有一個事件,你可以做到這一點。請查詢this answer以獲取有關收集已更改事件的更多詳細信息。

希望它有幫助。

+0

這也聽起來像它將依賴於底層集合中的順序,而不是ListView中的順序?此外,我試圖遠離修改ViewModel。 –

+0

集合的順序是Lisview的順序。這就是視圖模型的用途。提供表示邏輯層。你問了一個MVVM的方式來做到這一點。如果你不想修改你的虛擬機,而不是尋找一種MVVM友好的方式;) – Ninglin

+0

項目負責人希望視圖模型與表單邏輯完全分離。此時可接受的解決方案完全在xaml中,或者是轉換器的組合或者表單的少量代碼。 –

1

另一種可能性是將項目作爲命令參數傳遞。

<ListView x:Name="lstBox" 
        Background="Yellow" 
        ItemsSource="{Binding People}"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <WrapPanel> 
         <TextBlock Text="{Binding FirstName}" /> 
         <Button Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListView}}, 
                Path=DataContext.AddPersonCommand}" 
           CommandParameter="{Binding}" 
           Content="Add Person" 
           Visibility="{Binding IsEnabled, 
                RelativeSource={RelativeSource Self}, 
                Converter={StaticResource BooleanToVisibilityConverter}}" /> 
        </WrapPanel> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 

只有當項目在集合中最後一個時,該命令的CanExecute纔會返回true。這樣的事情:

private bool CanAddPerson(object arg) 
    { 

     return _people.Last().Equals(arg); 
    } 
+0

但是,這取決於作爲底層集合中最後一個的項目嗎?要求是它的ListView中的最後一項,而不管集合中的位置,例如 - 如果ListView是通過某種排序或其他排序? –

相關問題