У меня есть простой ListView с триггером, также я использую mvvm light RelayCommand. Главный вопрос: почему, когда функция ChangeShowingMode(ObservableCollection<Employee> items)
срабатывает в консоли, отображается только Firing: 0
. Почему он не показывает также Firing: 1
, Firing: 5
, Firing: 11
, Firing: 99
. Как это сделать?ListView странное поведение с смешением смешивания
XMLNS: я = "http://schemas.microsoft.com/expression/2010/interactions" XMLNS: е = "http://schemas.microsoft.com/expression/2010/interactivity"
<Grid>
<ListView ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<CheckBox IsChecked="{Binding IsChecked}" VerticalAlignment="Center">
<ei:Interaction.Triggers>
<ei:EventTrigger EventName="Checked">
<ei:InvokeCommandAction Command="{Binding DataContext.IsCheckedTrueCommand,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Views:MainWindow}}}" CommandParameter="{Binding .}"/>
</ei:EventTrigger>
</ei:Interaction.Triggers>
</CheckBox>
<Label Grid.Column="1" Content="{Binding Name}" VerticalAlignment="Center"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
код выглядит следующим образом:
namespace WpfApplication
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ListViewModel();
}
}
public class Employee : ViewModelBase
{
private bool isChecked;
public bool IsChecked
{
get
{
return this.isChecked;
}
set
{
this.isChecked = value;
this.RaisePropertyChanged("IsChecked");
}
}
public string Name { get; set; }
}
public class ListViewModel : ViewModelBase
{
private ObservableCollection<Employee> items;
public ObservableCollection<Employee> Items
{
get
{
return this.items;
}
set
{
this.items = value;
this.RaisePropertyChanged("Items");
}
}
public ListViewModel()
{
Items = new ObservableCollection<Employee>();
LoadAsync();
}
public void LoadAsync()
{
Task t = null;
t = Task.Factory.StartNew(new Action(() =>
{
System.Threading.Thread.Sleep(5000);
ObservableCollection<Employee> temporaryItems = new ObservableCollection<Employee>();
for (int i = 0; i < 100; i++)
{
temporaryItems.Add(new Employee { IsChecked = false, Name = i.ToString() });
}
Items = temporaryItems;
}));
t.ContinueWith((key) => { ChangeShowingMode(Items); });
}
public void ChangeShowingMode(ObservableCollection<Employee> items)
{
Items[0].IsChecked = true;
Items[1].IsChecked = true;
Items[5].IsChecked = true;
Items[11].IsChecked = true;
Items[99].IsChecked = true;
}
public RelayCommand<Employee> IsCheckedTrueCommand
{
get
{
return new RelayCommand<Employee>((emp) => Command(emp));
}
}
public void Command(Employee emp)
{
Console.WriteLine("Firing: {0}", emp.Name);
}
}
}
Если предположить, что '' IsChecked' поднимает INPC.PropertyChanged' событие, я предполагаю, что это делать с, что вы делаете вы это из 'Задачи'. Вы можете изменить свойство «Employee.IsChecked» на любом из них с помощью события «PropertyChanged», которое должно быть повышено в потоке пользовательского интерфейса (через 'Dispatcher') – dkozl
Вы ошибаетесь, потому что t.ContinueWith ((key) => {ChangeShowingMode (Items);}); Восстанавливает поток пользовательского интерфейса. Я думаю, проблема связана с виртуализацией или чем-то еще такого рода. – A191919
Нет, это не так. Пока вы не укажете подходящий 'TaskScheduler', например' TaskScheduler.FromCurrentSynchronizationContext() ' – dkozl