[英]UWP ListView Multi-Selection binding with MVVM Model
我正在嘗試在 UWP 中實現多選列表視圖,同時盡可能接近 MVVM model。我的問題是我無法通過綁定在視圖模型中獲取所選項目。
查看關於 SO 的其他答案,我發現實現此目的的唯一可能方法是通過ListView
的Command
和CommandParameter
字段進行綁定。 然而,答案通常要么集中在簡單的代碼隱藏方法上,要么是使用 WPF 做出的,這導致我無法執行命令。
在我的 MWE 之前的一個簡短說明:該程序將 a.pdf 文件作為輸入並通過將每個頁面轉換為BitmapImage
來顯示它。 我想要的是 select 這些單頁(BitmapImages)並對所有選定項目執行操作(在本例中為不同的操作;但是,我的 MWE 僅包含一個按鈕)。 我正在嘗試在 UWP 中實現多選列表視圖,同時盡可能接近 MVVM model。我的問題是我無法通過綁定在視圖模型中獲取所選項目。
這是我的 MWE:
Model
public class PdfPageModel
{
public string Title { get; set; }
public PdfDocument PdfDoc { get; set; }
public PdfPageModel(string Title, PdfDocument pdfdoc)
{
this.Title = Title;
this.PdfDoc = pdfdoc;
}
看法
<ListView
x:Name="PdfPageViewer"
CanReorderItems="True" AllowDrop="True" CanDragItems="True"
ItemsSource="{x:Bind ViewModel.PdfPages}"
IsItemClickEnabled="True"
SelectionMode="Multiple"
IsMultiSelectCheckBoxEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.IsHorizontalRailEnabled="True"
ScrollViewer.ZoomMode="Enabled"
IsZoomedInView="False"
>
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding }"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal">
</StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<Button
CommandParameter="{Binding SelectedItems, Mode=OneWay, ElementName=PdfPageViewer}"
Command="{x:Bind ViewModel.SelectedPagesCommand}"
/>
視圖模型
public ObservableCollection<BitmapImage> PdfPages { get; set; }
private ICommand _selectedPagesCommand;
public ICommand SelectedPagesCommand
{
get
{
if (_selectedPagesCommand == null)
{
_selectedPagesCommand = new RelayCommand<?>(async () =>
{
// ??
});
}
return _selectedPagesCommand;
}
}
我終於找到了如何實現這一目標。 對於任何好奇的人,或者也在這個問題上絆倒的人,這就是我所做的。
我找到了這個線程,它幾乎解決了我試圖做的事情。
OP 實現了一個轉換器(見下文)以從列表中獲取所有選定的項目作為ListView
元素。 從文檔中,我了解到SelectedItems
屬性的返回類型是List
接口IList<>
,我在我的SelectedPagesCommand
中實現了它。
然后,他們在命令調用中使用了這個轉換器。 (請注意, SelectedItems
調用已被刪除,因為使用轉換器后不再需要它。這是必要且重要的步驟。)有了這個,我終於能夠在列表中獲取選定的元素。 返回的元素是System.__ComObject
類型,而不是預期的類型。 不過,這很容易規避; 簡單地將類型轉換為它應該的類型(在我的例子中,它是一個簡單的BitmapImage
)。
轉換器
public class ListViewSelectedItemsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
var listView = value as ListView;
return listView.SelectedItems;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
看法
<Page.Resources>
<helper:ListViewSelectedItemsConverter x:Key="ListViewSelectedItemsConverter"/>
</Page.Resources>
<!-- ... -->
<ListView
x:Name="PdfPageViewer"
CanReorderItems="True" AllowDrop="True" CanDragItems="True"
ItemsSource="{x:Bind ViewModel.PdfPages}"
IsItemClickEnabled="True"
SelectionMode="Multiple"
IsMultiSelectCheckBoxEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.IsHorizontalRailEnabled="True"
ScrollViewer.ZoomMode="Enabled"
IsZoomedInView="False"
>
<ListView.ItemTemplate>
<DataTemplate>
<Image Source="{Binding }"/>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Orientation="Horizontal">
</StackPanel>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
<Button
CommandParameter="{Binding ElementName=PdfPageViewer, Converter={StaticResource ListViewSelectedItemsConverter}}"
Command="{x:Bind ViewModel.SelectedPagesCommand}"
/>
視圖模型
public ObservableCollection<BitmapImage> PdfPages { get; set; }
private ObservableCollection<BitmapImage> _selectedPdfPages;
public ObservableCollection<BitmapImage> SelectedPdfPages { get; set; }
private ICommand _selectedPagesCommand;
public ICommand SelectedPagesCommand
{
get
{
if (_selectedPagesCommand == null)
{
_selectedPagesCommand = new RelayCommand<IList<object>>(async param =>
{
foreach (var i in param)
{
var img = i as BitmapImage;
SelectedPdfPages.Add(img);
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.