У меня есть одно представление, которое выполняет задачи через ICommand. Представление выполняет задачу по списку выбранных элементов из списка. Я получаю список выбранного элемента через событие selection_changed в коде позади. Действие по этим элементам выполняется с помощью команды. Список выбранных элементов в модели просмотра не совпадает между двумя вызовами. Выбран список выбранных элементов после выбора элементов, список выбранных элементов, на которые ссылается команда, пуст. Я решил, что список не восстанавливается и не очищается, проверяя адреса памяти списков. Адреса памяти разные.Несколько экземпляров ViewModel
Почему у меня есть два экземпляра SelectedPrices?
Просмотр XAML
...
<Window.Resources>
<viewModels:AdminViewModel x:Key="ViewModel" />
</Window.Resources>
<Window.DataContext>
<viewModels:AdminViewModel/>
</Window.DataContext>
<ListView x:Name="lvCustomerPrices"
HorizontalAlignment="Left"
Margin="14,82,0,32"
Width="1362"
ItemsSource="{Binding Prices}"
Grid.ColumnSpan="3"
SelectionChanged="lvCustomerPrices_SelectionChanged">
...
View Code Behind
public partial class ExportAdminView : Window
{
protected AdminViewModel ViewModel
{
get { return (AdminViewModel)Resources["ViewModel"]; }
}
public ExportAdminView()
{
InitializeComponent();
}
private void lvCustomerPrices_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
ViewModel.SetSelectedPrices(lvCustomerPrices.SelectedItems.Cast<DailyCustomerPrice>());
}
}
Просмотр модели
public class AdminViewModel : INotifyPropertyChanged
{
public List<DailyCustomerPrice> SelectedPrices { get; set; } = new List<DailyCustomerPrice>();
public bool CanExportToEmail => (SelectedPrices.Count > 0 && !string.IsNullOrEmpty(ExportEmailAddress));
public ICommand ExportPricesToEmailCommand { get; set; }
public AdminViewModel()
{
ExportPricesToEmailCommand = new RelayCommand(ExportPrices,() => CanExportToEmail);
PriceEffectiveDate = DateTime.Now.Date.AddDays(1);
}
public void SetSelectedPrices(IEnumerable<DailyCustomerPrice> selectedItems)
{
SelectedPrices.Clear();
SelectedPrices.AddRange(selectedItems);
}
}
RelayCommand (мне нужно очистить это и сделать отдельный класс для параметров)
public class RelayCommand : ICommand
{
private Action<object> _executeWithParameter;
private Action _execute;
private Func<bool> _canExecute;
private event EventHandler CanExecuteChangedInternal;
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{}
public RelayCommand(Action execute) : this(execute, DefaultCanExecute)
{}
public RelayCommand(Action execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException(nameof(execute));
if (canExecute == null)
throw new ArgumentNullException(nameof(canExecute));
this._execute = execute;
this._canExecute = canExecute;
}
public RelayCommand(Action<object> execute, Func<bool> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException(nameof(execute));
}
if (canExecute == null)
{
throw new ArgumentNullException(nameof(canExecute));
}
this._executeWithParameter = execute;
this._canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
this.CanExecuteChangedInternal -= value;
}
}
public bool CanExecute()
{
return _canExecute();
}
public bool CanExecute(object parameter)
{
return CanExecute();
}
public void Execute(object parameter)
{
Execute();
}
bool ICommand.CanExecute(object parameter)
{
return CanExecute();
}
void ICommand.Execute(object parameter)
{
Execute();
}
public void Execute()
{
_execute();
}
public void OnCanExecuteChanged()
{
EventHandler handler = this.CanExecuteChangedInternal;
//DispatcherHelper.BeginInvokeOnUIThread(() => handler.Invoke(this, EventArgs.Empty));
handler?.Invoke(this, EventArgs.Empty);
}
public void Destroy()
{
_canExecute =() => false;
_executeWithParameter = _ => { return; };
_execute = null;
}
private static bool DefaultCanExecute()
{
return true;
}
}
Выбранныеценки в свойстве AdminViewModel.CanExportToEmail имеют другой адрес памяти, чем выбранныецены в методе SetSelectedPrices.
Мне нужно, чтобы они были в синхронизации.
При добавлении элемента в него, не добавлено ли другому? –
Да. Элементы, добавленные в событие SelectionChanged, не существуют в свойстве CanExportToEmail, но элементы, добавленные в событие selectionChanged, сохраняются в его копии списка, когда событие снова срабатывает. Кроме того, я могу добавить элемент в коллекцию SelectedPrices в свойстве CanExportToEmail через отладчик, и они также сохраняются между вызовами. – TonyStewart871
Я думаю, есть шанс, что у вас есть два экземпляра 'AdminViewModel'; если это так, то значение «этого» в этих двух местах должно также отличаться. –