Re: Стандартизация поведения окон программы
От: RushDevion Россия  
Дата: 23.09.10 10:32
Оценка:
Я бы предложил такой подход (только в качестве идеи).
Пишем классы поведения, каждый из которых отвечает за какой-то аспект поведения контрола (подписавшись на соотв. события)
Скажем CloseOnEsc(Form form) и т.п.
Делаем базовую форму с абстрактным методом, в потомках применяем нужное поведение к нужным контролам.
Понятное дело, такой подход применим если требуемого поведения можно добиться через публичный интерфейс соотвествующего контрола,
иначе без наследования никак не получится обойтись.

И примерчик:
public partial class SomeForm : Form
    {
        ArrayList behaviors = new ArrayList();

        public SomeForm()
        {
            InitializeComponent();            
        }

        protected override void OnHandleCreated( EventArgs e )
        {
            base.OnHandleCreated( e );
            behaviors.Clear();
            behaviors.Add( new CloseOnEsc( this ) );
            behaviors.Add( new ComboBoxPrompt( comboBox1, ProvidePrompts ) );
        }

        protected override void OnHandleDestroyed( EventArgs e )
        {
            for ( int i = behaviors.Count - 1; i >= 0; --i )
            {
                IDisposable disp = behaviors[i] as IDisposable;
                if ( null != disp )
                    disp.Dispose();
                behaviors.RemoveAt( i );
            }
            base.OnHandleDestroyed( e );
        }

        IEnumerable<string> ProvidePrompts( string str )
        {
            if ( str.StartsWith( "A" ) )
            {
                yield return "AA";
                yield return "AAAA";
                yield return "AAAAAA";
            }
        }        
    }

    public sealed class CloseOnEsc : IDisposable
    {
        readonly SomeForm Target;
        bool disposed;

        public CloseOnEsc( SomeForm form )
        {
            Target = form;
            Target.PreviewKeyDown += Target_PreviewKeyDown;
        }

        public void Dispose()
        {
            if ( !disposed )
            {
                Target.PreviewKeyDown -= Target_PreviewKeyDown;
                disposed = true;
            }
        }

        void Target_PreviewKeyDown( object sender, PreviewKeyDownEventArgs e )
        {
            if ( e.KeyCode == Keys.Escape )
            {
                Target.Close();
            }
        }
    }

    public sealed class ComboBoxPrompt : IDisposable
    {
        readonly ComboBox Target;
        Func<string, IEnumerable<string>> GetVariants;
        bool disposed;

        public ComboBoxPrompt( ComboBox cb, Func<string, IEnumerable<string>> getVariants )
        {
            Target = cb;
            Target.TextChanged += Target_TextChanged;
            GetVariants = getVariants;
        }

        void Target_TextChanged( object sender, EventArgs e )
        {
            string text = Target.Text ?? "";
            IEnumerable ie = GetVariants( text );
            Target.BeginUpdate();
            Target.Items.Clear();
            foreach ( string str in ie )
                Target.Items.Add( str );
            Target.EndUpdate();
            Target.Select( text.Length, 0 );
        }

        public void Dispose()
        {
            if ( !disposed )
            {
                Target.TextChanged -= Target_TextChanged;
                disposed = true;
            }
        }
    }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.