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