2011-07-20 7 views
0

私は比較的新しいWPFです。少し問題があります。 HierarchicalDataTemplatesを使用して、XMLをTreeViewコントロールに正常にバインドしました。各ノードは正しくレンダリングされます(SubstepTemplateのラベルを含む)。HierarchicalDataTemplate内のXPathを使用したCommandParameterのバインド

CommandParameterのハードコードされた値(999など)を入力した場合に限り、私のViewModelのバインドされたコマンドをSubstepTemplateのButtonから取得することもできます。私のXMLのcommandID属性へのバインドに失敗しました。ここで

私が今持っているものです。

XML:

<root xmlns=""> 
    <step label="Step Label 1"> 
    <button label="Button Title 1A" commandID="701" /> 
    <button label="Button Title 1B" commandID="702" /> 
    <button label="Button Title 1C" commandID="703" /> 
    </step> 
    <step label="Step Label 2"> 
    <button label="Button Title 2A" commandID="801" /> 
    <button label="Button Title 2B" commandID="802" /> 
    </step> 
</root> 

XAML:

<ResourceDictionary 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:local="clr-namespace:SidePanel"> 

<HierarchicalDataTemplate 
      x:Key="SubstepTemplate" 
      DataType="button" 
      ItemsSource="{Binding XPath=*}"> 
    <StackPanel Orientation="Horizontal"> 
     <Button Margin="2" Width="32" Height="32" Command="{Binding ElementName=MyTreeView, Path=DataContext.PluginCommand}" CommandParameter="{Binding [email protected]}" /> 
     <Label VerticalAlignment="Center" Margin="8,0,0,0" Content="{Binding [email protected]}" /> 
    </StackPanel> 
</HierarchicalDataTemplate> 

<HierarchicalDataTemplate 
      x:Key="StepTemplate" 
      DataType="step" 
      ItemsSource="{Binding XPath=*}" 
      ItemTemplate="{StaticResource SubstepTemplate}"> 
    <Expander Header="{Binding Mode=OneWay, [email protected]}" HorizontalAlignment="Stretch"> 
    </Expander> 
</HierarchicalDataTemplate> 

<Style TargetType="{x:Type local:SidePanelControl}"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type local:SidePanelControl}"> 
       <TreeView 
        Name="MyTreeView" 
        ItemsSource="{Binding XmlRoot}" 
        ItemTemplate="{StaticResource StepTemplate}" 
        Background="{TemplateBinding Background}" 
        BorderBrush="{TemplateBinding BorderBrush}" 
        BorderThickness="{TemplateBinding BorderThickness}" 
        HorizontalAlignment="Stretch"> 
       </TreeView> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 
</ResourceDictionary> 

のViewModelスニペット:

public DelegateCommand<string> PluginCommand 
    { 
     get 
     { 
      if (pluginCommand == null) 
      { 
       pluginCommand = new DelegateCommand<string>(ExecPluginCommand, canExecPluginCommand); 
      } 
      return pluginCommand; 
     } 
    } 

    public void ExecPluginCommand(string param) 
    { 
     LogMessage("In ExecPluginCommand, param = " + param); 
    } 

    public bool canExecPluginCommand(string param) 
    { 
     return true; 
    } 

正しいバインディング式である何そのnこれを動作させるには、CommandParameterを使用しますか? {バインディングXPath = @ commandID}は機能していないように見えます。

+0

それがあれば、に役立つかもしれない、GetCommandDataTypeで

data is System.Xml.XmlNode 

に対して明示的に(オブジェクトデータ)をテストしてから.Valueのメンバーを返すことのcommandId値を取得することができました「動作していない」に加えて、期待される動作と実際の動作を指定します。 – LarsH

+0

CommandParameter = "999"を指定した場合、ボタンをクリックすると、VMのmy DelegateCommand が起動します。しかし、XMLからのcommandID値が必要なのですか?私が試したすべてのBinding文は、DelegateCommandの結果は決して解けません。 – allendav

答えて

0

問題が見つかりました。 XPathがCommandParameterバインディングとして使用されると、テンプレート化されたDelegateCommandは文字列ではなくSystem.Xml.XmlNode型のパラメータを受け取ります。

のTypeConverter :: CanConvertFromがタイプSystem.Xml.XmlNodeの引数をどうするかを知らなかったため、コマンドデータ型

void ICommand.Execute(object parameter) 
    { 
     TParam value = GetCommandDataType(parameter); 
     Execute(value); 
    } 

を取得しようとしたとき、私は私のコマンドで例外を得ていました。

私はすなわち

 else if (data is System.Xml.XmlNode) 
     { 
      System.Xml.XmlNode foo = (System.Xml.XmlNode)data; 
      string fooVal = foo.Value; 
      TypeConverter converter = TypeDescriptor.GetConverter(typeof(string)); 
      result = (TParam)converter.ConvertFrom(fooVal); 
     } 
関連する問題