2010-07-23 64 views
9

我有TreeView控件,我想將樹節點的IsExpanded屬性綁定到我的DataSource項目!Silverlight樹形視圖。無法綁定「IsExpanded」屬性

但我有一個例外:

System.Windows.Markup.XamlParseException occurred 
    Message=Set property '' threw an exception. 

    StackTrace: 
     at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator) 
     at SilverlightTree.BSTreeView.InitializeComponent() 
     at SilverlightTree.BSTreeView..ctor() 
    InnerException: System.NotSupportedException 
     Message=Cannot set read-only property ''. 
     StackTrace: 
      at MS.Internal.XamlMemberInfo.SetValue(Object target, Object value) 
      at MS.Internal.XamlManagedRuntimeRPInvokes.SetValue(XamlTypeToken inType, XamlQualifiedObject& inObj, XamlPropertyToken inProperty, XamlQualifiedObject& inValue) 
     InnerException: 

內部異常:

{System.NotSupportedException: Cannot set read-only property ''. 

XAML:

<Grid x:Name="LayoutRoot"> 
    <controls:TreeView Name="treeView" SelectedItemChanged="treeView_SelectedItemChanged" 
         Style="{Binding TreeViewConnectingLines}" BorderBrush="{x:Null}"> 
     <controls:TreeView.ItemTemplate> 
      <toolkit:HierarchicalDataTemplate ItemsSource="{Binding Children}"> 
       <StackPanel Orientation="Horizontal" Background="Transparent"> 
        <toolkitDrag:ContextMenuService.ContextMenu> 
         <toolkitDrag:ContextMenu Loaded="ContextMenu_Loaded" 
               Opened="ContextMenu_Opened"/> 
        </toolkitDrag:ContextMenuService.ContextMenu> 
        <Image Source="{Binding Path=Type.Icon}" Width="20" Height="20" /> 
        <TextBlock Text="{Binding Path=FullDescription}" Height="20" 
           TextAlignment="Center" HorizontalAlignment="Center" /> 
       </StackPanel> 
      </toolkit:HierarchicalDataTemplate> 
     </controls:TreeView.ItemTemplate> 
     <controls:TreeView.ItemContainerStyle> 
      <Style TargetType="controls:TreeViewItem"> 
       <Setter Property="IsExpanded" Value="{Binding IsExpanded}"></Setter> 
      </Style> 
     </controls:TreeView.ItemContainerStyle>  
    </controls:TreeView> 
</Grid> 

和數據項:

public interface INode 
{ 
    NodeType Type { get; set; } 
    bool IsSelected { get; set; } 
    bool IsExpanded { get; set; } 
    List<INode> Children{get;set;}; 
} 
+3

SDK和工具包的版本?你相信這與'IsExpanded'屬性有什麼關係?如果您刪除了「ItemContainerStyle」,那麼異常消失了嗎? – AnthonyWJones 2010-07-23 09:04:28

+1

「如果刪除ItemContainerStyle,異常消失了嗎?」 是的!異常消失! 工具包:http://www.microsoft.com/silverlight/ – Evgeny 2010-07-23 09:28:33

回答

7

最快的辦法是繼承兩個TreeViewTreeViewItem,例如:

public class BindableTreeViewItem : TreeViewItem 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     var itm = new BindableTreeViewItem(); 
     itm.SetBinding(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay }); 

     return itm; 
    } 
} 

public class BindableTreeView : TreeView 
{ 
    protected override DependencyObject GetContainerForItemOverride() 
    { 
     var itm = new BindableTreeViewItem(); 
     itm.SetBinding(TreeViewItem.IsExpandedProperty, new Binding("IsExpanded") { Mode = BindingMode.TwoWay }); 

     return itm; 
    } 
} 

不幸的是,當你做了子類,你會失去TreeView的默認主題化。這是Silverlight主題概念的一個弱點。因此,您可以使用自定義的附加屬性行爲,該行爲遍歷樹並從外部設置綁定。由於樹節點是按需創建的,所以您必須爲每個尚未呈現的節點一次收聽Expanded事件,然後在等待每個節點後爲其每個子節點設置該事件處理程序中的綁定佈局通行證。

+1

SetBinding不需要1個參數! – Evgeny 2010-07-26 15:51:23

+2

@Evgeny ooops,我的壞...編輯答案以將缺少的參數添加到.SetBinding(...)方法調用中。 – herzmeister 2010-07-26 16:50:07

4

我只想指出現在這是可能的。我正在使用Silverlight 5,以及針對SL5編譯的Silverlight Toolkit,並且您可以綁定到IsExpanded。我的確定義了與你不同的地方。這是我的XAML。

<controls:TreeView ItemsSource="{Binding Repository.MajorClasses}" ItemTemplate="{StaticResource TreeviewMajorClassTemplate}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}"> 
      <controls:TreeView.Resources> 
       <Style TargetType="controls:TreeViewItem"> 
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" /> 
       </Style> 
      </controls:TreeView.Resources> 
     </controls:TreeView> 

如果你想知道,SelectedItem綁定會給出警告(因爲它仍然是TreeView的只讀屬性)。

真的不想提出一箇舊的線程,但這是我在這個主題上看到的最新的線程,並且認爲它對於人們知道它實際上工作是有用的。

+0

感謝您的更新,但對我來說這並沒有奏效。請參閱下面的答案。 – Rogier 2012-07-24 12:28:14

1

爲了跟進Malcom,我使用ItemContainerStyle而不是SL5工作。

<sdk:TreeView.ItemContainerStyle> 
     <Style TargetType="sdk:TreeViewItem"> 
      <Setter Property="IsExpanded" Value="True"/> 
      <Setter Property="Visibility" Value="{Binding IsVisible, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" /> 
     </Style> 
    </sdk:TreeView.ItemContainerStyle> 
1

如果您使用的是SL5,那麼標準的XAML設置工具應該可以工作。但是,如果您使用的是SL4或以下版本,則需要使用SetterValueBindingHelperhere。那麼你的XAML將如下所示。請確保您仔細複製下面的內容。

<sdk:TreeView.ItemContainerStyle> 
    <Style TargetType="sdk:TreeViewItem"> 
     <Setter Property="local:SetterValueBindingHelper.PropertyBinding"> 
      <Setter.Value> 
       <local:SetterValueBindingHelper> 
        <local:SetterValueBindingHelper Property="IsSelected" Binding="{Binding Mode=TwoWay, Path=IsSelected}"/> 
        <local:SetterValueBindingHelper Property="IsExpanded" Binding="{Binding Mode=TwoWay, Path=IsExpanded}"/> 
       </local:SetterValueBindingHelper> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</sdk:TreeView.ItemContainerStyle> 

語法與您在WPF中使用的不完全相同,但它的工作原理和工作原理都很好!