命令绑定到UserControl

时间:2015-06-17 22:04:33

标签: c# wpf mvvm

我目前正在努力让某些事情发挥作用,这在我看来似乎并不那么难。

A获得了一个显示在窗口中的TopLevel用户控件:

<UserControl.Resources>

    <DataTemplate DataType="{x:Type viewModels:PCodeViewModel}">
        <controls:PCodeTabControl />
    </DataTemplate>
    <DataTemplate x:Key="TabItemHeaderTemplate">
        <TextBlock FontWeight="Medium" Text="{Binding}" />
    </DataTemplate>
    <Style x:Key="TabItemStyle" TargetType="{x:Type dx:DXTabItem}">
        <Setter Property="Header" Value="{Binding TabHeader}" />
        <Setter Property="Content" Value="{Binding}" />
    </Style>
    <DataTemplate DataType="{x:Type viewModels:MexCompileViewModel}">
        <controls:MexCompileTabControl  />
    </DataTemplate>
</UserControl.Resources>
<Grid>
    <dx:DXTabControl ItemContainerStyle="{StaticResource TabItemStyle}"
                     ItemHeaderTemplate="{StaticResource TabItemHeaderTemplate}"
                     ItemsSource="{Binding Tabs}" />
</Grid>

相应的ViewModel在这里:

private ICommand createNewProjectCommand;

    private string sandboxRoot;

    public MatlabBuildViewModel()
    {
        this.Init();
    }

    public void Init()
    {
        this.InitTabs();
    }

    public void InitTabs()
    {
        this.Tabs = new ObservableCollection<TabViewModelBase>
                        {
                            new MexCompileViewModel(),
                            new PCodeViewModel()
                        };
        this.SandboxRoot = @"E:\_SupportTools\CaseManager";
    }

    public ObservableCollection<TabViewModelBase> Tabs { get; private set; }

    public void NotifyChildren()
    {
        Messenger.Default.Send(new SandboxRootUpdated());
    }

    public string SandboxRoot
    {
        get
        {
            return this.sandboxRoot;
        }

        set
        {
            if (value != null)
            {
                this.sandboxRoot = value;
                this.OnPropertyChanged();
                this.NotifyChildren();
            }
        }
    }

    /// <summary>
    /// Gets the create new project command.
    /// </summary>
    public ICommand CreateEmptyProjectCommand
    {
        get
        {
            if (this.createNewProjectCommand == null)
            {
                this.createNewProjectCommand = new DelegateCommand(Debugger.Break);
            }

            return this.createNewProjectCommand;
        }
    }

现在您可以看到我通过为targetType MexCompileViewModel和PCodeViewModel提供DataTemplate来显示两个选项卡。

Dattemplate绑定的两个userControl共享一个包含许多按钮的公共UserControl。

以下是MexCompileTabControl示例

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <compositeControls:MexCompileGrid Grid.Column="0" IsEnabled="{Binding IsEnabled}" />
    <StackPanel Grid.Column="1">
        <compositeControls:CommonActionsControl />
    </StackPanel>
</Grid>

CommonActionsControl只是一个带按钮的StackPanel:

<StackPanel helpers:MarginSetter.Margin="3">
    <GroupBox Header="MatlabProject-File">
        <StackPanel helpers:MarginSetter.Margin="3">
            <Button Command="{Binding CreateEmptyProjectCommand}" Content="Create empty project-file" />
            <Button Content="Refresh" />
        </StackPanel>
    </GroupBox>
    <GroupBox Header="Actions">
        <StackPanel helpers:MarginSetter.Margin="3">
            <Button Content="Clean" />
            <Button Content="Rebuild" />
            <Button Content="Generate m-Script" />
        </StackPanel>
    </GroupBox>
</StackPanel>

代码背后:

        public CommonActionsControl()
    {
        this.InitializeComponent();
    }

    public static readonly DependencyProperty CreateEmptyProjectCommandProperty = DependencyProperty.Register("CreateEmptyProjectCommand", typeof(ICommand), typeof(CommonActionsControl), new PropertyMetadata(default(ICommand)));

    public ICommand CreateEmptyProjectCommand
    {
        get
        {
            return (ICommand)GetValue(CreateEmptyProjectCommandProperty);
        }

        set
        {
            this.SetValue(CreateEmptyProjectCommandProperty, value);
        }
    }

所以我想要实现的是: 我的命令在TopLevelViewModel中定义。现在我希望我的CommonActionsControl继承这些命令,因为Control应该多次使用。你能帮我解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

由于CommonActionsControl显示TopLevelViewModel中定义的常见操作,因此将它们作为TopLevelView的一部分而不是在每个标签上显示都是有意义的。

如果你真的希望它们在每个标签上,那么我说你最好的办法是将命令添加到你的TabViewModelBase中,以便各种标签视图可以绑定到它们。你仍然可以在TopLevelViewModel中实现它们一次,然后通过在构造函数中注入它们将它们传递到各个选项卡VM中。