在嵌套用户控件wpf中定义的访问命令

时间:2017-02-10 22:13:36

标签: c# wpf command

我有一个来自MainWindow课程的Window。该窗口有一个ContentControl,用于托管其中的用户UserControl个对象。我正在尝试创建一个按钮,该按钮将访问嵌套Command中定义的UserControl。唯一的诀窍是我的用户控件实际上也有更多的嵌套在其中的用户控件,而我实际上是为了孙子命令,而不仅仅是一个孩子。像这样:

主窗口:

<metro:MetroWindow  x:Class="GrimshawRibbon.Revit.Wpf.MainWindow"
                    x:Name="win"
                    xmlns:metro="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
                    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                    xmlns:pmModel="clr-namespace:GrimshawRibbon.Revit.Management.ParametersManagerWPF.ViewModel"
                    xmlns:pmLocal="clr-namespace:GrimshawRibbon.Revit.Management.ParametersManagerWPF"
                    xmlns:local="clr-namespace:GrimshawRibbon.Revit.Wpf"
                    mc:Ignorable="d" Height="400" Width="600" ResizeMode="CanResizeWithGrip" 
                    Title="{Binding WindowTitle, Mode=OneWay, FallbackValue='GrimshawDT'}" BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1"
                    WindowStartupLocation="CenterScreen" WindowTransitionsEnabled="False">
    <metro:MetroWindow.Resources>
        <ResourceDictionary>
            <DataTemplate DataType="{x:Type pmModel:pmViewModel}">
                <pmLocal:pmMain />
            </DataTemplate>
        </ResourceDictionary>
    </metro:MetroWindow.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height = "100" />
            <RowDefinition/>
        </Grid.RowDefinitions>

        <ContentControl x:Name="MainContentControl" Content="{Binding CurrentPageViewModel}" Margin="10" Grid.Row="1"/>
        <Button x:Name="btnOK" Content="OK" Margin="0,0,211,10" HorizontalAlignment="Right" Width="75" Height="36" VerticalAlignment="Bottom" Command="{Binding pmModel:pmViewModel.ApplyCommand, Mode=OneWay}" Grid.Row="1" metro:ButtonHelper.CornerRadius="0" metro:ControlsHelper.ContentCharacterCasing="Normal" BorderThickness="1" metro:ButtonHelper.PreserveTextCase="True"/>
    </Grid>
</metro:MetroWindow>

嵌套在MainWindow中的控件:

<UserControl x:Class="GrimshawRibbon.Revit.Management.ParametersManagerWPF.pmMain"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
             xmlns:ignore="http://www.ignore.com"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:GrimshawRibbon.Revit.Management.ParametersManagerWPF" 
             xmlns:viewModel="clr-namespace:GrimshawRibbon.Revit.Management.ParametersManagerWPF.ViewModel"
             xmlns:Custom="http://metro.mahapps.com/winfx/xaml/controls"
             mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="600">
    <UserControl.Resources>
        <ResourceDictionary>
            <DataTemplate DataType="{x:Type viewModel:pmSetParamToValueViewModel}">
                <local:pmSetParamToValueView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewModel:pmCopyParamToParamViewModel}">
                <local:pmCopyParamToParamView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewModel:pmCopyParamToParamSliceViewModel}">
                <local:pmCopyParamToParamSliceView />
            </DataTemplate>
            <DataTemplate DataType="{x:Type viewModel:pmCombineTwoSlicesViewModel}">
                <local:pmCombineTwoSlicesView />
            </DataTemplate>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <ComboBox x:Name="cbType" Margin="0,26,0,0" Height="22" VerticalAlignment="Top" ItemsSource="{Binding PageNames}" SelectedIndex="{Binding SelectedVMIndex}" Custom:TextBoxHelper.Watermark="Parameter Manager Functionality"/>
        <ContentControl x:Name="contentControl" Content="{Binding CurrentPageViewModel}" Margin="0,57,0,0"/>
        <Label x:Name="label" Content="Select Functionality:" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold"/>
    </Grid>
</UserControl>

这反过来有更多嵌套控件,如下所示:

<UserControl x:Class="GrimshawRibbon.Revit.Management.ParametersManagerWPF.pmSetParamToValueView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:GrimshawRibbon.Revit.Management.ParametersManagerWPF"
             xmlns:Custom="http://metro.mahapps.com/winfx/xaml/controls" 
             mc:Ignorable="d" d:DesignWidth="600" d:DesignHeight="200">
    <Grid>
        <ComboBox x:Name="cbCategories" HorizontalAlignment="Left" VerticalAlignment="Top" Width="180" ItemsSource="{Binding Categories}" DisplayMemberPath="Name" SelectedItem="{Binding SelectedCategory}" Custom:TextBoxHelper.Watermark="Category" Margin="0,26,0,0"/>
        <ComboBox x:Name="cbSourceParam" HorizontalAlignment="Left" Margin="0,57,0,0" Width="180" Height="22" VerticalAlignment="Top" ItemsSource="{Binding Parameters}" DisplayMemberPath="Name" SelectedItem="{Binding SelectedParameter}" Custom:TextBoxHelper.Watermark="Source Parameter"/>
        <TextBox x:Name="tbParamValue" Margin="185,57,0,0" Height="23" VerticalAlignment="Top" Text="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Custom:TextBoxHelper.Watermark="Parameter Value"/>
        <Label x:Name="label" Content="Define Parameters:" HorizontalAlignment="Left" VerticalAlignment="Top" FontWeight="Bold"/>
    </Grid>
</UserControl>

现在,当在主窗口中点击OK按钮时,我希望第二个嵌套控件执行ApplyCommand。这是我的第二个用户控件的视图模型:

namespace GrimshawRibbon.Revit.Management.ParametersManagerWPF.ViewModel
{
    public class pmSetParamToValueViewModel : ViewModelBase
    {
        public pmModel model;
        public ObservableCollection<CategoryWrapper> Categories { get; private set; }
        public RelayCommand ApplyCommand { get; private set; }

        public pmSetParamToValueViewModel(Document doc)
        {
            this.model = new pmModel(doc);
            this.Categories = model.CollectCategories();
            SelectedCategory = Categories[0];
            this.ApplyCommand = new RelayCommand(this.Apply);
        }

        // logic for apply button
        private void Apply()
        {
            model.Apply(SelectedCategory.ID, SelectedParameter, null, null, Value, null, null, null, "Apply");
        }

        // logic for storing parameter value
        private string _value;
        public string Value
        {
            get { return _value; }
            set
            {
                if (_value == value) return;

                _value = value;
                RaisePropertyChanged(() => Value);
            }
        }

        // storage for source parameters
        private ObservableCollection<ParameterWrapper> _parameters;
        public ObservableCollection<ParameterWrapper> Parameters
        {
            get { return _parameters; }
            set
            {
                if (_parameters == value) return;

                _parameters = value;
                RaisePropertyChanged(() => Parameters);
                if (Parameters.Count > 0)
                {
                    SelectedParameter = Parameters[0];
                }
            }
        }

        // logic for selected category
        private CategoryWrapper _selectedCategory;
        public CategoryWrapper SelectedCategory
        {
            get { return _selectedCategory; }
            set
            {
                if (_selectedCategory == value) return;

                _selectedCategory = value;
                RaisePropertyChanged(() => SelectedCategory);
                Parameters = model.CollectParameters(SelectedCategory.ID, new string[] { "String", "Double", "Integer" });
            }
        }

        // logic for selected source parameter
        private ParameterWrapper _selectedParameter;
        public ParameterWrapper SelectedParameter
        {
            get { return _selectedParameter; }
            set
            {
                if (_selectedParameter == value) return;

                _selectedParameter = value;
                RaisePropertyChanged(() => SelectedParameter);
            }
        }
    }
}

有人可以告诉我如何在主窗口中设置OK按钮,以便能够访问嵌套用户控件中定义的命令。或者有一种方法可以设置一个OK按钮来检索给定嵌套用户控件的当前状态,这样我就可以检索它们的属性并将它们用作ApplyCommand的参数?

干杯!

1 个答案:

答案 0 :(得分:1)

看起来您已经在主视图模型中引用了子视图模型,所以我相信这应该有用:

<Button x:Name="btnOK" Content="OK" Margin="0,0,211,10" HorizontalAlignment="Right" Width="75" Height="36" VerticalAlignment="Bottom" Command="{Binding CurrentPageViewModel.CurrentPageViewModel.ApplyCommand}" Grid.Row="1" metro:ButtonHelper.CornerRadius="0" metro:ControlsHelper.ContentCharacterCasing="Normal" BorderThickness="1" metro:ButtonHelper.PreserveTextCase="True"/>