Silverlight树视图.无法绑定"IsExpanded"属性

Iev*_*ida 9 data-binding silverlight wpf treeview

我有TreeView控制权,我想将树节点的IsExpanded属性绑定到我的DataSource项目!

但我有一个例外:

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: 
Run Code Online (Sandbox Code Playgroud)

内在异常:

{System.NotSupportedException: Cannot set read-only property ''.
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

和数据项:

public interface INode
{
    NodeType Type { get; set; }
    bool IsSelected { get; set; }
    bool IsExpanded { get; set; }
    List<INode> Children{get;set;};
}
Run Code Online (Sandbox Code Playgroud)

her*_*ter 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,TreeView当你进行子类化时,你将失去默认主题.这是Silverlight主题概念的弱点.因此,您也可以使用自定义附加属性或遍历树的行为,并从外部设置绑定.因为树节点是按需延迟创建的,所以你必须Expanded为每个尚未渲染的节点监听一次事件,然后在等待布局后为每个子节点设置该事件处理程序中的绑定通过.

  • @Evgeny ooops,我的错...编辑了答案,将缺少的参数添加到.SetBinding(...)方法调用中. (2认同)