开发者

Expander IsExpanded binding

In the following code:

http://msdn.microsoft.com/en-us/library/ms754027.aspx

How to Bind IsExpanded to the MyData list of objects, where each object has 开发者_运维百科the IsExpanded property?

<Expander IsExpanded={Binding Path=IsExpanded, Mode=TwoWay} />

This doesn't work!

MyData is List<GroupNode>;

GroupNode is a class containing notify property changed property IsExpanded.

So, if I open one of the expander manually it should set the IsExpanded property to true of that MyData's GroupNode.


It's not very easy to do, because the DataContext of the GroupItem is an instance of CollectionViewGroup, and this class doesn't have a IsExpanded property. You can however specify a converter in the GroupDescription, allowing you to return a custom value for the "name" of the group (the CollectionViewGroup.Name property). This "name" can be anything; in your case, you need it to be a class that wraps the group name (e.g. grouping key) and has a IsExpanded property:

Here's an example:

public class ExpandableGroupName : INotifyPropertyChanged
{
    private object _name;
    public object Name
    {
        get { return _name; }
        set
        {
            if (_name != value)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    private bool? _isExpanded = false;
    public bool? IsExpanded
    {
        get { return _isExpanded; }
        set
        {
            if (_isExpanded != value)
            {
                _isExpanded = value;
                OnPropertyChanged("IsExpanded");
            }
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion

    public override bool Equals(object obj)
    {
        return object.Equals(obj, _name);
    }

    public override int GetHashCode()
    {
        return _name != null ? _name.GetHashCode() : 0;
    }

    public override string ToString()
    {
        return _name != null ? _name.ToString() : string.Empty;
    }
}

And here's the converter:

public class ExpandableGroupNameConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new ExpandableGroupName { Name = value };
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var groupName = value as ExpandableGroupName;
        if (groupName != null)
            return groupName.Name;
        return Binding.DoNothing;
    }

    #endregion
}

In XAML, just declare the grouping as follows:

<my:ExpandableGroupNameConverter x:Key="groupConverter" />
<CollectionViewSource x:Key='src' 
                      Source="{Binding Source={StaticResource MyData}, 
                               XPath=Item}">
  <CollectionViewSource.GroupDescriptions>
    <PropertyGroupDescription PropertyName="@Catalog" Converter="{StaticResource groupConverter}" />
  </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

And bind the IsExpanded property like that:

<Expander IsExpanded={Binding Path=Name.IsExpanded} />
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜