我们在一个新的Silverlight项目中使用Caliburn.Micro,并且每个人都工作得很好。内置约定将按钮单击事件绑定到viewModel,但我不确定在datagrids和comboboxes上处理selectionChanged事件的最佳方法是什么。
目前,我绑定到所选项目并调用自定义逻辑,但我觉得这有点代码味道,我应该分离属性和selectedChange事件的设置。但是,如果我将它们分开,如何通过命令将选择更改事件绑定到我的viewModel?还是一个EventTrigger?或者下面的代码是否可以接受?这是一个很小的变化,但我到处都是这个逻辑。
private Foo _selectedFoo;
public Foo SelectedFoo
{
get
{
return _Foo;
}
set
{
if (_Foo != null && _Foo.Equals(value)) return;
_Foo = value;
NotifyOfPropertyChange("SelectedFoo");
NotifyOfPropertyChange("CanRemove");
LoadRelatedBars();
}
}
答案 0 :(得分:19)
我经常使用这种技术,我觉得很舒服。
我发现VM很好地反应了它自己的状态变化,而不需要外部actor(顺便提一下是View,但也可能是另一个组件)来设置新状态,然后告诉VM该状态是改变。
但是,如果您真的想要,可以使用Message.Attach附加属性将View中的事件挂钩到VM中的操作:
cal:Message.Attach="[Event SelectionChanged] = [OnSelectionChangedAction]"
答案 1 :(得分:1)
以下是MVVM和Caliburn.Micro使用的示例。像SelectionChanged这样的一些动作应该得到一个明确的事件参数,所以你应该在caliburn事件动作部分设置它。通常第一个参数是传递$ this(动作附加到的实际ui元素。)并且你在处理程序中获取行的datacontext但是要到达Grid,你应该传递$ source,作为第一个参数($ source - 是触发ActionMessage发送的实际FrameworkElement。根据手册Caliburn manual。
XAML
cal:Message.Attach="[Event SelectionChanged]=[Action DataGrid_JobTypesSelectionChanged($source,$eventArgs)];"
代码:
public void DataGrid_JobTypesSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var grid = sender as DataGrid;
JobTypesSelectedCollection = grid.SelectedItems.Cast<JobComplexModel>().ToList();
}