我有一个ViewModel集合,它们使用样式呈现为制表符,以提取要在选项卡上显示的相关内容:
public class TabViewModel : DependencyObject
{
public object Content
{
get { return (object)GetValue(ContentProperty); }
set
{
SetValue(ContentProperty, value);
}
}
}
这是TabControl:
<TabControl
ItemsSource={Binding MyCollectionOfTabViewModels}"
ItemContainerStyle="{StaticResource TabItemStyle}" />
这是风格
<Style TargetType="TabItem" x:Key="TabItemStyle">
<Setter Property="Content" Value="{Binding Content}"/>
</Style>
我们正在创建一个usercontrol实例,并将TabViewModel的“Content”属性设置为该属性,以便user控件显示在TabItem的Content区域中。
MyCollectionOfViewModels.Add(new TabViewModel()
{
Content = new MyUserControl();
});
我的问题是,我想允许添加到TabViewModel的Content属性的MyUserControl(或其任何子控件)引发TabViewModel处理的事件。
任何人都知道我会这样做吗?
我们已经尝试过使用RoutedEvents和RoutedCommands,但是无法让任何东西100%工作并让它与MVVM兼容。我真的认为这可以通过RoutedEvent或RoutedCommand完成,但我似乎无法使其工作。
注意:我已经删除了一些相关的Prism特定代码,但是如果你想知道我们为什么这么傻,那是因为我们试图通过使用Prism的RegionManager来保持控制不可知。
答案 0 :(得分:2)
您可以向TabViewModel添加State属性,并检查DependencyPropertyChanged事件。
想象一下以下的枚举:
public enum TabViewModelState
{
True,
False,
FileNotFound
}
然后将State属性添加到此枚举的TabViewModel:
public static readonly DependencyProperty StateProperty =
DependencyProperty.Register("State", typeof(TabViewModelState), typeof(TabViewModel), new PropertyMetadata(OnStateChanged));
private static void OnStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
TabViewModel viewModel= (TabViewModel)obj;
//Do stuff with your viewModel
}
在控件中使用对此属性的双向绑定:
<CheckBox Checked="{Binding Path=State, Converter={StaticResource StateToBooleanConverter}, Mode=TwoWay}" />
最后但并非最不重要的是实现转换器,该转换器将转换为控件所需的原始值..(在我的示例中为boolean&lt; - &gt; TabViewModelState):
public class StateToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
TabViewModelState state = (TabViewModelState) value;
return state == TabViewModelState.True;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool result = (bool) value;
return result ? TabViewModelState.True : TabViewModelState.False;
}
}
所以现在你有一个由UI管理的State属性,并在你需要响应时抛出已更改的事件。
希望这有帮助!
答案 1 :(得分:1)
如果你在ViewModel上放一个命令并且只是从你的UserControl绑定它,那么无论如何都会触发它。你不必冒泡它,UserControl只会找到命令并使用它。
如果您的ViewModel上有一个委托命令“GoCommand”,那么您的UserControls按钮绑定将如下所示:
<Button Command="{Binding GoCommand}" >Go</Button>
我经历了同样的思考过程,认为UserControl需要冒泡命令,但它不会 - 绑定只会在ViewModel上找到命令时自行挂起。
希望这会有所帮助,我不会错过这一点! ;)
答案 2 :(得分:1)
你应该看看Marlon Grech的Attached Command Behavior,它允许你将ViewModel命令附加到GUI事件。