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# 我如何调度同一个方法以多次调用,并在WPF应用程序中提供调用顺序号作为参数?_C#_Wpf_Lambda_Dispatcher - Fatal编程技术网

C# 我如何调度同一个方法以多次调用,并在WPF应用程序中提供调用顺序号作为参数?

C# 我如何调度同一个方法以多次调用,并在WPF应用程序中提供调用顺序号作为参数?,c#,wpf,lambda,dispatcher,C#,Wpf,Lambda,Dispatcher,我只需要为每个视图模型分派一个方法一次,所有方法都很好地工作。现在我需要为其中一个视图模型(下面的ObjectViewModel)分派SelectedObjectsChanged调用2次,所以我为这两个方法引入了属性NumberOfCalls和参数。然而,SelectedObjectsChanged只被调用一次,参数callNumber的值是错误的(2),而我认为第一次是0,第二次是1。应该如何正确地做到这一点 interface ISelectedObjectDependent { v

我只需要为每个视图模型分派一个方法一次,所有方法都很好地工作。现在我需要为其中一个视图模型(下面的ObjectViewModel)分派SelectedObjectsChanged调用2次,所以我为这两个方法引入了属性NumberOfCalls和参数。然而,SelectedObjectsChanged只被调用一次,参数callNumber的值是错误的(2),而我认为第一次是0,第二次是1。应该如何正确地做到这一点

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评论。