我正在项目中使用具有委托访问权限的RelayCommand。这是一个有行为的电话。当我在ViewModel中使用Directly时,它可以正常工作。
但是我想在一个类中传递这个命令以便一般地使用它。行为仍然有效,但没有生命的迹象。
我的ViewModel(工作)中的命令:
LoadCommand = new RelayCommand<object>( new Action<object>(
obj =>
{
if (Busy)
return;
Busy = true;
System.Threading.ThreadPool.QueueUserWorkItem(
delegate
{
Application.Current.Dispatcher.BeginInvoke(new Action(
delegate
{
// myReference.AddDatas(Mvts);
AddMoreItems();
Busy = false;
}));
});
}));
我新课程中的命令(不起作用):
public Action<object> LoadCommand(Ref<ObservableCollection<T>> myList)
{
return new Action<object>(
obj =>
{
if (Busy)
return;
Busy = true;
System.Threading.ThreadPool.QueueUserWorkItem(
delegate
{
Application.Current.Dispatcher.Invoke(new Action(
delegate
{
AddDatas(myList);
Busy = false;
}));
});
}));
使用
进行通话LoadCommand = new RelayCommand<object>(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;
}
}
尽管在两种情况下都达到了 atEnd.Execute(null);
但是当命令在其他文件中执行以下属性时IsAlive = False
当命令直接在VM中执行时IsAlive与我的目标对象
为True答案 0 :(得分:1)
这两个是完全不同的,第一个是某种属性,它显示了正确的Command绑定,第二个是返回RelayCommand的方法。我不认为你可以将Command属性绑定到方法。这可能是它无法运作的原因。
答案 1 :(得分:1)
没有机会拨打Command
,因为您呼叫的不是viewModel
的同一个实例。
要在viewModel
中从另一个viewModel
执行某些操作(例如,运行您的命令或编辑某些属性),最好使用EventAggregator pattern
。
在我看来,最好的方法是使用Prism框架的EventAggregator模式。 Prism简化了MVVM模式。但是,如果您没有使用过Prism,可以使用Rachel Lim的教程 - simplified version of EventAggregator pattern by 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” });
然后您在另一个MainViewModel的构造函数中订阅一个事件:
eventAggregator.GetEvent<ChangeStockEvent>().Subscribe(ShowNews);
public void ShowNews(TickerSymbolSelectedMessage msg)
{
// Handle Event
}
Rachel Lim的简化方法是我见过的最好的方法。但是,如果要创建大型应用程序,则应阅读this article by Magnus Montin和at CSharpcorner with an example。