1
我已经从Window
类派生的MainWindow
。该窗口有一个ContentControl
,用于托管用户UserControl
中的对象。我正在尝试创建一个按钮,该按钮将访问在嵌套UserControl
中定义的Command
。唯一的窍门是,我的用户控件实际上嵌套了更多的用户控件,而我实际上是为了使用grand-child命令而不是仅仅是一个孩子。事情是这样的:访问命令WPF
主窗口:即嵌套到主窗口
<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>
控制:
<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>
现在,当在主窗口中点击确定按钮时,我想要第二个嵌套控件执行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
的参数?
干杯!
是的,这个伟大的工程。谢谢。我会奖赏你的赏金。然而,我意识到我所要求的并不是我真正想要做的。我并不总是有一个用户控件嵌套在另一个用户控件中。有时(大部分时间)我只有一个用户控件。为了处理这两种情况下我想结合这个按钮,像这样'绑定CurrentPageViewModel.ApplyCommand'然后把'ApplyCommand'和'Apply'方法的主要用户控件中,如果可能从那里走。有没有办法从'ViewModel'中的代码访问我的嵌套控件? – konrad
问题是'CurrentPageViewModel'是一个基类'ViewModelBase',并且不允许我访问它里面的方法。由于当前页面可以是任何视图模型,我需要将其转换为选定的特定模型,然后才能访问其方法。 :-(我可以实现我自己的基本视图模型,并添加应用方法它,因此它总是可用的。那是很长的路要走? – konrad
我不能肯定我明白了,所以道歉,如果这不工作,你的场景,但也许你可以按照你的建议将你的按钮绑定到CurrentPageViewModel.ApplyCommand,但是沿着这条线: 如果(this.CurrentPageViewModel!= null) {0127}这个当前页面模型.ApplyCommand.Execute() } 其他 { this.Apply();} 我 –