我有一个通过ICommand执行任务的视图。该视图对列表视图中的所选项目列表执行任务。我通过后面的代码中的selection_changed事件获得所选项目的列表。对这些项的操作是通过命令执行的。视图模型中所选项目的列表在两个调用之间不匹配。选择项目后所选项目的列表是正确的,该命令引用的所选项目列表为空。我确定列表没有通过检查列表的内存地址进行重新实例化或清除。内存地址不同。
为什么我有两个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">
...
查看代码背后
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属性中的SelectedPrices与SetSelectedPrices方法中的SelectedPrices具有不同的内存地址。
我需要这些同步。
答案 0 :(得分:4)
要解决您的问题,请从XAML或代码隐藏中删除AdminViewModel
。
要在Code-Behind中访问它,请使用AdminViewModel
抓住(AdminViewModel)this.DataContext
。
干杯
答案 1 :(得分:1)
删除
<Window.Resources>
<viewModels:AdminViewModel x:Key="ViewModel" />
</Window.Resources>
<Window.DataContext>
<viewModels:AdminViewModel/>
</Window.DataContext>
试试这个;
public ExportAdminView()
{
this.DataContext = new AdminViewModel();
InitializeComponent();
}