将冒泡的RoutedEvent或RoutedCommand传递到ViewModel

5

我有一组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>

我们正在创建一个用户控件的实例,并将TabViewModel的“Content”属性设置为该实例,以便在TabItem的内容区域中显示该用户控件。
MyCollectionOfViewModels.Add(new TabViewModel() 
{ 
     Content = new MyUserControl();
});

我的问题是,我想允许添加到TabViewModel的Content属性的MyUserControl(或其任何子控件)引发TabViewModel处理的事件。 有人知道我该如何做吗? 我们尝试使用RoutedEvents和RoutedCommands进行实验,但是我们无法使其100%地工作并与MVVM兼容。 我真的认为可以使用RoutedEvent或RoutedCommand来完成此操作,但似乎我无法使其正常工作。 注意:我已删除了一些相关的Prism特定代码,但如果您想知道为什么我们会做这样的事情,那是因为我们正在尝试通过使用Prism的RegionManager来保持控件不可知性。
3个回答

2
你可以给TabViewModel添加一个State属性,并检查DependencyPropertyChanged事件。
假设有以下枚举:
public enum TabViewModelState
{
    True,
    False,
    FileNotFound
}

然后在您的TabViewModel中添加一个State属性,其类型为此枚举:
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}" />

最后但同样重要的是,实现转换器,以便控件可以将值转换为所需的原始值并从中进行转换(例如,在我的示例中,布尔值<-->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属性,并在需要响应时引发更改事件。
希望这可以帮到您!

这非常接近我所寻找的。谢谢! - Anderson Imes

1

1

如果您在ViewModel上放置一个命令,并且只是从UserControl绑定到该命令,它将会被触发。您不必冒泡它,UserControl将会找到该命令并使用它。

如果您在ViewModel上有一个委托命令'GoCommand',那么您的UserControl按钮绑定看起来就像这样:

<Button Command="{Binding GoCommand}" >Go</Button>

我曾经也有过同样的思维过程,认为UserControl需要向上传递命令,但实际上并不需要——只要ViewModel中存在该命令,绑定就会自动完成。

希望这能有所帮助,并且我没有误解您的意思!;)


那并不是我正在寻找的,但很可能是因为我没有添加足够的细节。我稍微改变了问题。 - Anderson Imes
希望这样更清楚...我需要在TabViewModel中处理事件/命令,而不是"MyUserControl"的视图模型。我意识到我可以在MyUserControlViewModel中添加一个命令,但我不想要那个。我想在MyUserControlViewModel中执行一些代码,然后在TabViewModel中处理它。 - Anderson Imes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接