Silverlight дерево. Невозможно связать свойство IsExpanded - PullRequest
9 голосов
/ 23 июля 2010

У меня есть 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: 

внутреннее исключение:

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

Ответы [ 4 ]

7 голосов
/ 23 июля 2010

Самый быстрый способ - создать подклассы TreeView и TreeViewItem, например:

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 один раз для каждого узла, который еще не был отрисован, а затем установить привязки в этом обработчике событий для каждого из его дочерних элементов после ожиданиядля макета пропуска.

4 голосов
/ 27 сентября 2011

Я просто хотел указать, что это теперь возможно.Я использую Silverlight 5 вместе с Silverlight Toolkit, скомпилированным для SL5, и вы можете связать его с 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).

Не очень хотелосьподнять старую ветку, но это была самая свежая тема, которую я видел по этой теме, и для людей было бы полезно узнать, что она действительно работает.

1 голос
/ 10 февраля 2013

Если вы используете SL5, тогда должны работать стандартные установщики XAML. Но, если вы используете SL4 или ниже, вам нужно будет использовать SetterValueBindingHelper из здесь . Тогда ваш 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, но он работает и работает хорошо!

1 голос
/ 24 июля 2012

Чтобы продолжить работу над 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>
...