5

我有一组 ViewModels,它们使用一种样式呈现为选项卡,以提取相关内容以显示在选项卡上:

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 的“内容”属性设置为这样,以便用户控件显示在 TabItem 的内容区域中。

MyCollectionOfViewModels.Add(new TabViewModel() 
{ 
     Content = new MyUserControl();
});

我的问题是,我想允许添加到 TabViewModel 的 Content 属性的 MyUserControl(或其任何子控件)被允许引发 TabViewModel 处理的事件

有人知道我会怎么做吗?

我们已经尝试使用 RoutedEvents 和 RoutedCommands,但无法让任何东西 100% 工作并使其与 MVVM 兼容。我真的认为这可以通过 RoutedEvent 或 RoutedCommand 来完成,但我似乎无法让它工作。

注意:我已经删除了一些与 Prism 相关的特定代码,但如果您想知道为什么我们会做一些如此愚蠢的事情,那是因为我们试图通过使用 Prism 的 RegionManager 来保持与控制无关。

4

3 回答 3

2

您可以将 State 属性添加到 TabViewModel,并检查 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}" />

最后但并非最不重要的一点是实现转换器,该转换器将在控件所需的原始值之间进行转换..(在我的示例中为 boolean <--> 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 属性,并在你需要响应时引发更改的事件。

希望这可以帮助!

于 2009-08-17T08:39:33.330 回答
1

如果您在 ViewModel 上放置命令并从 UserControl 绑定到该命令,无论如何它都会触发。您不必冒泡它,UserControl 只会找到命令并使用它。

如果您的 ViewModel 上有一个委托命令“GoCommand”,那么您的 UserControls 按钮绑定将如下所示:

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

我经历了同样的思考过程,认为 UserControl 需要冒泡命令,但它没有 - 当它在 ViewModel 上找到命令时,绑定只会自行连接。

希望这会有所帮助,我没有错过重点!;)

于 2009-08-13T22:33:00.610 回答
1

您应该看看 Marlon Grech 的Attached Command Behavior,它允许您将 ViewModel 命令附加到 GUI 事件。

于 2009-08-17T08:17:50.893 回答