Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带有混合触发器的ListView奇怪行为_C#_Wpf_Listview_Mvvm - Fatal编程技术网

C# 带有混合触发器的ListView奇怪行为

C# 带有混合触发器的ListView奇怪行为,c#,wpf,listview,mvvm,C#,Wpf,Listview,Mvvm,我有一个带触发器的简单列表视图,我也在使用mvvm light RelayCommand。 主要的问题是为什么当控制台中的函数ChangeShowingMode(ObservableCollection items)触发时,它只显示触发:0。为什么它不同时显示触发:1,触发:5,触发:11,触发:99。怎么做 xmlns:i=”http://schemas.microsoft.com/expression/2010/interactions" xmlns:ei=”http://schemas.m

我有一个带触发器的简单列表视图,我也在使用mvvm light RelayCommand。 主要的问题是为什么当控制台中的函数
ChangeShowingMode(ObservableCollection items)
触发时,它只显示
触发:0
。为什么它不同时显示
触发:1
触发:5
触发:11
触发:99
。怎么做

xmlns:i=”http://schemas.microsoft.com/expression/2010/interactions" xmlns:ei=”http://schemas.microsoft.com/expression/2010/interactivity"


代码如下所示:

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);
    }
}
命名空间WpfApplication
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
DataContext=新的ListViewModel();
}
}
公共类雇员:ViewModelBase
{
私人住宅被检查;
公共场所被检查
{
得到
{
返回此。已检查;
}
设置
{
this.isChecked=值;
本.RaiseProperty已更改(“已检查”);
}
}
公共字符串名称{get;set;}
}
公共类ListViewModel:ViewModelBase
{
私人可观测收集项目;
公共可观测收集项目
{
得到
{
归还此物品;
}
设置
{
这个项目=价值;
本.增加财产变更(“项目”);
}
}
公共ListViewModel()
{
Items=新的ObservableCollection();
LoadAsync();
}
公共void LoadAsync()
{
任务t=null;
t=Task.Factory.StartNew(新操作(()=>
{
系统线程线程睡眠(5000);
ObservableCollection temporaryItems=新的ObservableCollection();
对于(int i=0;i<100;i++)
{
添加(新员工{IsChecked=false,Name=i.ToString()});
}
项目=临时项目;
}));
t、 继续((键)=>{ChangeShowingMode(项);});
}
公共作废更改显示模式(可观察到的收集项目)
{
项[0]。IsChecked=true;
项[1]。IsChecked=true;
项目[5]。IsChecked=true;
项[11]。IsChecked=true;
项[99]。IsChecked=true;
}
public relay命令是checkedtrue命令
{
得到
{
返回新的RelayCommand((emp)=>Command(emp));
}
}
公共无效命令(员工emp)
{
WriteLine(“激发:{0}”,emp.Name);
}
}

}

选中事件将仅针对可见复选框引发。因此,仅对可见的命令调用该命令

通过测试您提供的示例,属性是由任务设置的,并且也按照UI的预期反映出来。但该命令仅在我手动选中复选框时调用,而不是通过初始化

改变

t.ContinueWith((key) => { ChangeShowingMode(Items); });

结果是,为可见复选框调用该命令。 如果在显示复选框时取消勾选,则将为复选框99调用该命令

但这种行为一点也不奇怪。我认为,当您的viewmodel是否连接到Datacontext时,这是一个时间问题

您的问题“如何制作?”的答案取决于您当前解决方案的问题是什么

要查看属性更改,您可以 并在更改时调用命令

但我想你根本不需要这个。选中状态通过双向绑定由IsChecked属性反映

<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" VerticalAlignment="Center">
如果通过代码进行更改,则可以在viewmodel中手动调用该命令

Items[0].IsChecked = true;
if (IsCheckedTrueCommand.CanExecute(Items[0]))
    IsCheckedTrueCommand.Execute(Items[0]);
但我不确定你来不来。问题仍然是在增强的场景中命令应该做什么

顺便问一下,您使用的是哪个版本的框架?看

要在用户交互中调用Comand,您可以使用:

<CheckBox CommandParameter="{Binding}"
                              Command="{Binding DataContext.CheckBoxCommand, RelativeSource={RelativeSource FindAncestor,  AncestorType={x:Type Window}}}"
                              IsChecked="{Binding IsChecked, Mode=TwoWay}" VerticalAlignment="Center">


假设
已检查
引发
INPC.PropertyChanged
事件,我猜这与您从
任务中执行它有关。您可以更改
Employee.IsChecked
PropertyChanged
事件应在UI线程上引发(通过
Dispatcher
),因为t.ContinueWith((键)=>{ChangeShowingMode(Items);})是错误的;在UI线程上提升。我认为问题在于虚拟化或类似的东西。不,它不是。直到您指定适当的
任务调度器
,例如
任务调度器。FromCurrentSynchronizationContext()
如果它未在UI上更新,则不会引发异常。为什么会引发异常。你只需提起这件事。在我的代码t.ContinueWith((key)=>{ChangeShowingMode(Items);})中,从之前和中登录到控制台当前线程ID;使用t.ContinueWith((键)=>{Syste.Threading.Thread.Sleep(5000);ChangeShowingMode(Items);});我想这也会让你感到惊讶。@A1919我检查了这个,看看我的最新答案。新年快乐!
var checkedItemsList = Items.Where(ele => ele.IsChecked).ToList();
Items[0].IsChecked = true;
if (IsCheckedTrueCommand.CanExecute(Items[0]))
    IsCheckedTrueCommand.Execute(Items[0]);
<CheckBox CommandParameter="{Binding}"
                              Command="{Binding DataContext.CheckBoxCommand, RelativeSource={RelativeSource FindAncestor,  AncestorType={x:Type Window}}}"
                              IsChecked="{Binding IsChecked, Mode=TwoWay}" VerticalAlignment="Center">