2011-07-20 37 views
0

我對WPF比較陌生,而且遇到了一些小問題。使用HierarchicalDataTemplates,我已成功將XML綁定到TreeView控件。每個節點都正確渲染(包括SubstepTemplate中的標籤)。問題在HierarchicalDataTemplate中使用XPath綁定CommandParameter

我甚至可以從SubstepTemplate中的Button中獲取ViewModel中的綁定命令,但前提是爲CommandParameter(例如999)輸入硬編碼值。所有嘗試綁定到我的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> 

視圖模型段:

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; 
    } 

什麼是正確的綁定表達式那個在CommandParameter中進行操作以獲得此功能? {綁定XPath = @ commandID}似乎不起作用,我不明白爲什麼不。

+0

也可能奏效,在除了「似乎不起作用」之外,您還可以指定預期行爲和實際行爲。 – LarsH

+0

如果我指定CommandParameter =「999」,則當我單擊按鈕時,我的VM中的DelegateCommand 會觸發。但是我想要的是XML中的commandID值 - 我試過的每一個Binding語句都會導致DelegateCommand永遠不會被觸發。 – allendav

回答

0

我發現了這個問題。當XPath用作CommandParameter綁定時,模板化的DelegateCommand將接收System.Xml.XmlNode類型的參數,而不是字符串。

我在我的命令試圖獲取命令數據類型

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

因爲類型轉換器:: CanConvertFrom不知道做什麼用型System.Xml.XmlNode的參數做的時候得到一個例外。

我能夠在GetCommandDataType明確地測試了

data is System.Xml.XmlNode 

(對象數據),然後返回.value的成員,以獲得commandID值,即

 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); 
     } 
相關問題