Простой RegionManager

в 18:10, , рубрики: .net, mvvm, Prism, wpf, разработка, метки: , , , ,

Многим известна библиотека Prism, но зачастую весь её обширный функционал ненужен. Иногда хочется воспользоваться некоторыми плюшками из этой библиотеки.
Просто так выдрать малый кусок кода не получается, тогда приходится создавать свою реализацию с более или менее приближенным функционалом.
RegionManager — одна из интересных плюшек, простую реализацию которой мы и рассмотрим

Сразу приведу примерный кусок кода с использованием:

xaml-объявляем регионы

<Grid x:Name="LayoutRoot" xmlns:service="clr-namespace:TestProgramm.Services">
        <DockPanel LastChildFill="True">
            <ContentControl DockPanel.Dock="Top" service:RegionManager.Region="TopPanel"/>
            <ContentControl DockPanel.Dock="Left" service:RegionManager.Region="LeftPanel"/>
            <ContentControl service:RegionManager.Region="Center"/>
        </DockPanel>
</Grid>

code-заполняем центральный регион

SimpleIoc.Default.GetInstance<RegionManager>().Set("Center",SimpleIoc.Default.GetInstance<HomeView>());

Здесь и в самой реализации буду использовать MVVM Light Toolkit, но его будет мало, что не критично и позволит не отвлекаться.

Собственно реализация класса RegionManager:

public class RegionManager
    {
        #region Регионы
        private Dictionary <String, DependencyObject> Regions = new Dictionary<string , DependencyObject>();
        #endregion

        /// <summary>
        /// Дерегистрация региона
        /// </summary>
        /// <param name="sender">элемент за которым закреплен регион</param>
        /// <param name="name">наименование региона</param>
        public void Unregister(DependencyObject sender, string name)
        {
            if (Regions.Contains(new KeyValuePair<String, DependencyObject>(name, sender)))
                Regions.Remove(name);
        }

        /// <summary>
        /// Регистрация региона
        /// </summary>
        /// <param name="sender">элемент за которым закрепляется регион</param>
        /// <param name="name">наименование региона</param>
        public void Register(DependencyObject sender, string name)
        {
            if (sender.GetType().GetProperty( "Content" ) == null )
                throw new ArgumentException();
            Regions[name] = sender;
        }

        /// <summary>
        /// Заполнить регион
        /// </summary>
        /// <param name="name">наименование региона</param>
        /// <param name="element">элемент, который вставляется в регион</param>
        public void Set(String name, object element)
        {
            if (Regions.ContainsKey(name))
                Regions[name].SetValue( ContentControl.ContentProperty, element);
        }

        #region Свойство Region
        public static String GetRegion( DependencyObject obj)
        {
            return (String )obj.GetValue(RegionProperty);
        }

        public static void SetRegion( DependencyObject obj, String value)
        {
            obj.SetValue(RegionProperty, value);
        }

        public static readonly DependencyProperty RegionProperty =
            DependencyProperty.RegisterAttached("Region" , typeof( String), typeof(RegionManager ), new UIPropertyMetadata(PropertyChanged));

        public static void PropertyChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (e.OldValue != null )
                ServiceLocator.Current.GetInstance<RegionManager >().Unregister(sender, e.OldValue as String );
            if (e.NewValue != null )
                ServiceLocator.Current.GetInstance<RegionManager >().Register(sender, e.NewValue as String);
        }
        #endregion
    }

ready.

Автор: ZloyRabadaber

* - обязательные к заполнению поля