wpf - BehaviorBase and one use examples

Behavior is something that we have know very good in the past that we can build something into the WPF system. There is Behavior class where can use as a base calss if we want to build our own behavior entities.

From its definition, you can see that  

msdn 写道
Encapsulates state information and zero or more ICommands into an attachable object.

 And we will demonstrate the use of  Behavior class with the following examples
we have some data model where we want to display the table with some ListView, while we don't want to hard-coded the  headers information because the table's metadata can change. so we will make a ListView behavior. 
so , we first define some helper classes. this is for the DependencyProperty helper classes. 

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace BehaviorBaseClass.Behaviors
{
    public static class DependencyPropertyExtensions
    {
        // Use Use this method with extreme caution - it can lead to memory leaks in case if you don't call RemovePropertyListener!
        public static void SetPropertyListener(
            this DependencyProperty property,
            object component,
            EventHandler handler)
        {
            var descriptor = DependencyPropertyDescriptor.FromProperty(property, component.GetType());
            if (descriptor != null)
                descriptor.AddValueChanged(component, handler);
        }

        public static void RemovePropertyListener(
            this DependencyProperty property,
            object component,
            EventHandler handler)
        {
            var descriptor = DependencyPropertyDescriptor.FromProperty(property, component.GetType());
            if (descriptor != null)
                descriptor.RemoveValueChanged(component, handler);
        }

        public static void RefreshPropertyValueFromBinding(
            this DependencyProperty property,
            DependencyObject component)
        {
            var binding = BindingOperations.GetBindingExpressionBase(component, property);
            if (binding != null)
                binding.UpdateTarget();
        }

    }
}

 
and below is the ListViewBehaivour classes.

using System;
using System.Collections;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Interactivity;

namespace BehaviorBaseClass.Behaviors
{
    public class ListViewBehaviour : Behavior<ListView>
    {
        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof (IEnumerable), typeof (ListViewBehaviour), new PropertyMetadata(OnDataSourceChanged));


        private ICollectionView _dataCollectionView;

        public IEnumerable DataSource
        {
            get { return (IEnumerable) GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }


        protected ICollectionView DataCollectionView
        {
            get { return _dataCollectionView; }
        }

        protected static void OnDataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = d as ListViewBehaviour;
            if (behavior == null) return;

            behavior.OnDataCollectionChanged(GetDefaultCollectionView(e.NewValue as IEnumerable));
        }



        protected virtual void OnDataCollectionChanged(ICollectionView newView = null)
        {
            _dataCollectionView = newView;
            PopulateColumns();
        }



        protected static ICollectionView GetDefaultCollectionView(IEnumerable enumerable)
        {
            if (enumerable == null)
                return null;
            return CollectionViewSource.GetDefaultView(enumerable);
        }

        private void PopulateColumns()
        {
            var gridView = AssociatedObject.View as GridView;

            var collection = _dataCollectionView as ICollectionView;
            if (gridView != null && collection != null)
            {
                gridView.Columns.Clear();
                foreach (var col in collection)
                {
                    var statusColumn = new GridViewColumn()
                                           {
                                               Header = col,
                                               DisplayMemberBinding = new Binding(col.ToString())
                                           };
                    gridView.Columns.Add(statusColumn);
                }
            }
        }

        private ICollectionView GetCollectionView()
        {
            return GetDefaultCollectionView(DataSource) ?? AssociatedObject.Items;
        }


        protected override void OnAttached()
        {
            base.OnAttached();
            ICollectionView view = GetCollectionView();
            ItemsControl.ItemsSourceProperty.SetPropertyListener(AssociatedObject, OnAssociatedObjectItemsSourceChanged);

        }

        private void OnAssociatedObjectItemsSourceChanged(object sender, EventArgs e)
        {
            PopulateColumns();
        }

        protected override void OnDetaching()
        {
            OnDataCollectionChanged();
        }
    }
}

 

As you can tell, you have to make your behavior class inherits from the Behavior<T> where the T is the Decorated classes, since we will decorate this behaviors on the ListViews, so we expand the T as the ListVIew. 

and you can use it as such .

        <ListView
                ItemsSource="{Binding RiskViewerService.RiskData}">
            <ListView.View>
                <GridView>
                </GridView>
            </ListView.View>
            <i:Interaction.Behaviors>
                <b:ListViewBehaviour DataSource="{Binding RiskViewerService.Columns}"></b:ListViewBehaviour>
            </i:Interaction.Behaviors>
        </ListView>

 

 

References:

Behavior Class: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值