C# 我如何调度同一个方法以多次调用,并在WPF应用程序中提供调用顺序号作为参数?
我只需要为每个视图模型分派一个方法一次,所有方法都很好地工作。现在我需要为其中一个视图模型(下面的ObjectViewModel)分派SelectedObjectsChanged调用2次,所以我为这两个方法引入了属性NumberOfCalls和参数。然而,SelectedObjectsChanged只被调用一次,参数callNumber的值是错误的(2),而我认为第一次是0,第二次是1。应该如何正确地做到这一点C# 我如何调度同一个方法以多次调用,并在WPF应用程序中提供调用顺序号作为参数?,c#,wpf,lambda,dispatcher,C#,Wpf,Lambda,Dispatcher,我只需要为每个视图模型分派一个方法一次,所有方法都很好地工作。现在我需要为其中一个视图模型(下面的ObjectViewModel)分派SelectedObjectsChanged调用2次,所以我为这两个方法引入了属性NumberOfCalls和参数。然而,SelectedObjectsChanged只被调用一次,参数callNumber的值是错误的(2),而我认为第一次是0,第二次是1。应该如何正确地做到这一点 interface ISelectedObjectDependent { v
interface ISelectedObjectDependent
{
void SelectedObjectsChanged(int callNumber);
int NumberOfCalls { get; }
int ExecutionOrder { get; }
bool NeedsRefresh(int callNumber);
}
public class SelectedObjects
{
private List<ISelectedObjectDependent> _viewModels;
public void ObjectSelectionChanged(object sender, EventArgs e)
{
foreach (var vm in _viewModels)
{
for (int i = 0; i < vm.NumberOfCalls; i++)
{
if (vm.NeedsRefresh(i))
{
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle,
(Action)(() =>
{
vm.SelectedObjectsChanged(i);
}));
}
}
}
}
}
public class ObjectViewModel : ViewModel, ISelectedObjectDependent
{
public int NumberOfCalls { get { return 2; } }
public int ExecutionOrder { get { return 1;} }
public bool NeedsRefresh(int callNumber)
{
return true;
}
public void SelectedObjectsChanged(int callNumber)
{
if (callNumber == 0)
{
if (IsObjectInfoVisible && IsObjectInformationExpanded)
RefreshObjectInfo(false);
}
else
{
if (IsObjectInfoVisible && IsObjectInformationExpanded)
ObjectProperties.Instance.UpdateRemainingAttributes();
}
}
}
接口已选择对象相关
{
void SelectedObjectsChanged(int callNumber);
int NumberOfCalls{get;}
int ExecutionOrder{get;}
bool NeedsRefresh(int callNumber);
}
公共类选定对象
{
私有列表视图模型;
public void ObjectSelectionChanged(对象发送方,事件参数e)
{
foreach(视图模型中的var vm)
{
for(int i=0;i
{
vm.选择的对象(i);
}));
}
}
}
}
}
公共类ObjectViewModel:ViewModel,ISelectedObjectDependent
{
public int NumberOfCalls{get{return 2;}}
public int ExecutionOrder{get{return 1;}}
公共bool NeedsRefresh(int callNumber)
{
返回true;
}
公共无效已选择对象已更改(int callNumber)
{
if(callNumber==0)
{
if(IsobjectInfo可见和IsobjectInformation扩展)
RefreshObjectInfo(错误);
}
其他的
{
if(IsobjectInfo可见和IsobjectInformation扩展)
ObjectProperties.Instance.UpdateMainingAttribute();
}
}
}
在所选对象更改执行时,该值已更改
var index = i;
App.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
vm.SelectedObjectsChanged(index);
}));
菲利普的有益评论
net中的所有委托样式代码块都具有相同的场景。如果你
在传递迭代变量时,直到
执行代码块。您认为在创建时会对其进行评估吗
代码块,但这是对代码的误读
lambda表达式不捕获变量
i
的值。相反,它捕获变量本身(可以这么说)。当lambda表达式最终通过dispatcher执行时,for循环已经完成,i
的值为2
。这就是调用SelectedObjectsChanged的值(实际上调用了两次,两次调用的参数都是2)解决方案:在for循环中创建一个变量,并将当前值赋值为i
。然后在lambda表达式中使用该变量,而不是i
(这是因为lambda也是for循环主体作用域的局部变量;也就是说,for循环的每次迭代都会创建一个新的捕获),谢谢@elgonzo!调用一次而不是两次的问题有点无关,所以引入新变量解决了我的问题。这是正确的解决方案,但因为.net中所有委托样式的代码块都有相同的场景。如果传递的是迭代变量,则在执行代码块之前不会对其求值。您认为在创建代码块时会对其进行评估,但这是对代码的误读。谢谢您的回答。参数现在是正确的,我找到了“调用一次而不是两次”的原因+@PhillipH的1个用于helpdul评论。