C# 在另一个类MVVM中调用RelayCommand

C# 在另一个类MVVM中调用RelayCommand,c#,wpf,mvvm,C#,Wpf,Mvvm,我正在项目中使用具有委托访问权限的RelayCommand。这是一个有行为的电话。当我直接在ViewModel中使用它时,效果很好 但是我想在类中传递这个命令,以便通用地使用它。该行为仍然有效,但没有命令生命的迹象 我的ViewModel(工作)中的命令: LoadCommand=new RelayCommand(新操作( obj=> { 如果(忙) 返回; 忙=真; System.Threading.ThreadPool.QueueUserWorkItem( 代表 { Application.

我正在项目中使用具有委托访问权限的RelayCommand。这是一个有行为的电话。当我直接在ViewModel中使用它时,效果很好

但是我想在类中传递这个命令,以便通用地使用它。该行为仍然有效,但没有命令生命的迹象

我的ViewModel(工作)中的命令:

LoadCommand=new RelayCommand(新操作(
obj=>
{
如果(忙)
返回;
忙=真;
System.Threading.ThreadPool.QueueUserWorkItem(
代表
{
Application.Current.Dispatcher.BeginInvoke(新操作(
代表
{
//myReference.AddDatas(Mvts);
AddMoreItems();
忙=假;
}));
});
})); 
我的新类中的命令(不起作用):

public Action加载命令(Ref myList)
{
返回新操作(
obj=>
{
如果(忙)
返回;
忙=真;
System.Threading.ThreadPool.QueueUserWorkItem(
代表
{
Application.Current.Dispatcher.Invoke(新操作(
代表
{
AddDatas(myList);
忙=假;
}));
});
}));
打电话给

LoadCommand = new RelayCommand<object>(myReference.LoadCommand(Mvts));
LoadCommand=newrelaycommand(myReference.LoadCommand(Mvts));
我所知道的是,在订单的开头放置断点后,不会调用它

有关更多信息,请在datagrid的滚动处于底部时调用LoadCommand

 public class ScrollViewerMonitor
{
    public static DependencyProperty AtEndCommandProperty
        = DependencyProperty.RegisterAttached(
            "AtEndCommand", typeof(ICommand),
            typeof(ScrollViewerMonitor),
            new PropertyMetadata(OnAtEndCommandChanged));

    public static ICommand GetAtEndCommand(DependencyObject obj)
    {
        return (ICommand)obj.GetValue(AtEndCommandProperty);
    }

    public static void SetAtEndCommand(DependencyObject obj, ICommand value)
    {
        obj.SetValue(AtEndCommandProperty, value);
    }


    public static void OnAtEndCommandChanged(
        DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)d;
        if (element != null)
        {
            element.Loaded -= element_Loaded;
            element.Loaded += element_Loaded;
        }
    }

    static void element_Loaded(object sender, RoutedEventArgs e)
    {
        FrameworkElement element = (FrameworkElement)sender;
        element.Loaded -= element_Loaded;
        ScrollViewer scrollViewer = FindChildOfType<ScrollViewer>(element);
        if (scrollViewer == null)
        {
            return;
        }

        var dpd = DependencyPropertyDescriptor.FromProperty(ScrollViewer.VerticalOffsetProperty, typeof(ScrollViewer));
        dpd.AddValueChanged(scrollViewer, delegate (object o, EventArgs args)
        {
            bool atBottom = scrollViewer.VerticalOffset
                           >= scrollViewer.ScrollableHeight;
            if (atBottom)
            {
                var atEnd = GetAtEndCommand(element);
                if (atEnd != null)
                {
                    atEnd.Execute(null);
                }
            }
        });
    }

    static T FindChildOfType<T>(DependencyObject root) where T : class
    {
        var queue = new Queue<DependencyObject>();
        queue.Enqueue(root);

        while (queue.Count > 0)
        {
            DependencyObject current = queue.Dequeue();
            for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
            {
                var child = VisualTreeHelper.GetChild(current, i);
                var typedChild = child as T;
                if (typedChild != null)
                {
                    return typedChild;
                }
                queue.Enqueue(child);
            }
        }
        return null;
    }
}
公共类ScrollViewerMonitor
{
公共静态从属属性AtEndCommandProperty
=DependencyProperty.RegisterAttached(
“ATEND命令”,类型为(ICommand),
类型(ScrollViewerMonitor),
新属性元数据(OnatedCommandChanged));
公共静态ICommand GetAtEndCommand(DependencyObject obj)
{
返回(ICommand)对象GetValue(AtEndCommandProperty);
}
公共静态void SetAtEndCommand(DependencyObject对象、ICommand值)
{
对象设置值(AtEndCommandProperty,值);
}
公共静态无效命令已更改(
DependencyObject d,DependencyPropertyChangedEventArgs e)
{
FrameworkElement=(FrameworkElement)d;
if(元素!=null)
{
element.Loaded-=element\u Loaded;
element.Loaded+=element_Loaded;
}
}
已加载静态无效元素(对象发送器,路由目标e)
{
FrameworkElement=(FrameworkElement)发送方;
element.Loaded-=element\u Loaded;
ScrollViewer ScrollViewer=FindChildOfType(元素);
如果(scrollViewer==null)
{
返回;
}
var dpd=DependencyPropertyDescriptor.FromProperty(ScrollViewer.VerticalOffsetProperty,typeof(ScrollViewer));
AddValueChanged(scrollViewer,委托(对象o,事件args args)
{
bool atBottom=scrollViewer.VerticalOffset
>=scrollViewer.ScrollableHeight;
如果(在底部)
{
var-atEnd=GetAtEndCommand(元素);
如果(atEnd!=null)
{
atEnd.Execute(null);
}
}
});
}
静态T FindChildOfType(DependencyObject根),其中T:class
{
var queue=新队列();
queue.Enqueue(root);
而(queue.Count>0)
{
DependencyObject当前=queue.Dequeue();

for(int i=VisualTreeHelper.GetChildrenCount(当前)-1;0这两个是完全不同的,第一个是某种显示正确命令绑定的属性,第二个是返回RelayCommand的方法。我认为您无法将命令属性绑定到方法。这可能是它无法工作的原因。

没有机会调用
命令,因为您正在调用与
视图模型的实例不同

要从另一个
viewModel
viewModel
中执行某些操作(例如,运行命令或编辑某些属性),最好使用
EventAggregator模式

在我看来,最好的方法是使用Prism框架的EventAggregator模式。Prism简化了MVVM模式。但是,如果您没有使用Prism,可以使用Rachel Lim的教程-。我强烈推荐您使用Rachel Lim的方法

如果使用Rachel Lim的教程,则应创建一个公共类:

public static class EventSystem
{...Here Publish and Subscribe methods to event...}
并将事件发布到您的OptionViewModel中:

eventAggregator.GetEvent<ChangeStockEvent>().Publish(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0” });
eventAggregator.GetEvent().Publish(
新的TickerSymbolSelectedMessage{StockSymbol=“STOCK0”});
然后在MainViewModel的另一个构造函数中订阅事件:

eventAggregator.GetEvent<ChangeStockEvent>().Subscribe(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}
eventAggregator.GetEvent().Subscribe(ShowNews);
public void ShowNews(TickerSymbolSelectedMessage msg)
{
//处理事件
}

Rachel Lim的简化方法是我见过的最好的方法。但是,如果你想创建一个大的应用程序,那么你应该阅读和。

请提供一些信息说明为什么它不起作用。另外,你是否尝试过调试新代码,并能给我们一些线索来寻找什么?你如何调用LoadComand(…)?您如何使用LoadCommand(..)返回的命令?可能您正在从各种实例或您的
viewModels
调用
command
?您确定这与您的
viewModel
是同一个实例吗?不,我认为在返回Action时,它到达atEnd.Execute(null)后不是同一个实例
eventAggregator.GetEvent<ChangeStockEvent>().Publish(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0” });
eventAggregator.GetEvent<ChangeStockEvent>().Subscribe(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}