Window
クラスから派生したMainWindow
があります。そのウィンドウには、ユーザーUserControl
をホストするために使用されるContentControl
があります。私はその中で定義されたCommand
にアクセスするボタンを作成しようとしていますUserControl
。唯一のトリックは、私のユーザーコントロールに実際に多くのユーザーコントロールがネストされていることです。実際には子供だけではなく、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>
今、メインウィンドウでOKボタンが押されると、この2番目のネストされたコントロールに0123を実行させます。これは私の第二のユーザコントロールのビューモデルである:
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つのユーザーコントロールを持っています。両方の場合を処理するために、 'Binding CurrentPageViewModel.ApplyCommand'のようにそのボタンをバインドし、' ApplyCommand'と 'Apply'メソッドをメインのユーザコントロールの中に入れて、可能であればそこから移動したいと思います。 'ViewModel'のコードからネストされたコントロールにアクセスする方法はありますか? – konrad
問題は、 'CurrentPageViewModel'が基本クラス' ViewModelBase'であり、その内部のメソッドにアクセスできないということです。現在のページはビューモデルのいずれかになる可能性があるので、そのメソッドにアクセスする前に、選択した特定のモデルにキャストする必要があります。 :-(私は自分のベースビューモデルを実装して、それに適用メソッドを追加して常に利用できるようにすることができます。 – konrad
これはあなたのことを理解しているとは思えません。場合によっては、CurrentPageViewModel.ApplyCommandにボタンをバインドすることもできますが、この行に沿って何かを行うことができます。 if(this.CurrentPageViewModel!= null) { this.CurrentPageViewModel.ApplyCommand.Execute() 他} { this.Apply(); } –