[英]Selected Items implementation in a ListBox acts odd in WPF and MVVM
我做了相當多的研究,以通過 WPF 中的 MVVM 實現選定的項目。 我以為我成功了,但現在選擇是根據滾動位置進行的。 我選擇了列表框中的所有項目,但只有前 11 個標記為選中。 如果我滾動更多,選擇更多。 如果我滾動到底部所有選定的項目。 這個問題有解決方案嗎?
XAML:
<ListBox x:Name="DataListBox" SelectionMode="Extended" HorizontalAlignment="Left" Margin="5,5,0,0" Grid.Row="1" Grid.Column="0" Grid.RowSpan="8" VerticalAlignment="Top" Height="200" Width="200" ItemsSource="{Binding DataListBoxItemsSource, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding DataListBoxSelectedItem, UpdateSourceTrigger=PropertyChanged}" > <ListBox.InputBindings> <KeyBinding Command="ApplicationCommands.SelectAll" Modifiers="Ctrl" Key="A" /> </ListBox.InputBindings> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="IsSelected" Value="{Binding IsSelected}"/> </Style> </ListBox.ItemContainerStyle> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged" > <i:CallMethodAction TargetObject="{Binding}" MethodName="DataListBox_SelectionChanged"/> </i:EventTrigger> </i:Interaction.Triggers> </ListBox>
查看模型
public async void CreateLayersTOC()
{
if (MapView.Active != null)
{
if (DataListBoxSelectedItem != null || FavoriteTabsSelectedItem != null)
MainStackPanelIsEnabled = false;
LayerNames = new List<string>();
await Task.Run(() =>
{
MessageBox.Show("source count " + DataListBoxItemsSource.Count);//58 items all selected
if (DataListBoxSelectedItem != null)
foreach (ItemPresenter itemP in DataListBoxItemsSource)
{
if (itemP.IsSelected)
{
if (LayerNames.Contains(itemP.ToString()) == false)
LayerNames.Add(itemP.ToString());
}
}
if (FavoriteTabsSelectedItem != null)
{
foreach (ItemPresenter itemP in FavListBoxItemsSource)
{
if (itemP.IsSelected)
{
if (LayerNames.Contains(itemP.ToString()) == false)
LayerNames.Add(itemP.ToString());
}
}
}
MessageBox.Show("Coll" + LayerNames.Count);//Count depends on scroll position
});
//do stuff
}
else
MessageBox.Show("Make sure to have a map available before adding layers to a map");
MainStackPanelIsEnabled = true;
}
public class ItemPresenter : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private readonly string _value;
public ItemPresenter(string value)
{
_value = value;
}
public override string ToString()
{
return _value;
}
private bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected != value)
{
_isSelected = value;
OnPropertyChanged();
}
}
}
}
下面是綁定 ListBox 的 SelectedItem 和 ListBoxItems 的 IsSelected 屬性所需的一切的簡單示例。
XAML:
<ListBox ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem}"
SelectionMode="Extended">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding Selected}"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
查看型號:
public class DataItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string Name { get; set; }
private bool selected;
public bool Selected
{
get { return selected; }
set
{
selected = value;
PropertyChanged?.Invoke(this,
new PropertyChangedEventArgs(nameof(Selected)));
Debug.WriteLine(Name + " selected: " + selected);
}
}
}
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<DataItem> Items { get; }
= new ObservableCollection<DataItem>();
public IEnumerable<DataItem> SelectedItems
{
get { return Items.Where(i => i.Selected); }
}
private DataItem selectedItem;
public DataItem SelectedItem
{
get { return selectedItem; }
set
{
selectedItem = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
}
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var vm = new ViewModel();
vm.Items.Add(new DataItem { Name = "Item 1" });
vm.Items.Add(new DataItem { Name = "Item 2" });
vm.Items.Add(new DataItem { Name = "Item 3" });
vm.Items.Add(new DataItem { Name = "Item 4" });
vm.Items.Add(new DataItem { Name = "Item 5" });
DataContext = vm;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.