Что такое WPF-эквивалент компонентов WinForms? - PullRequest
10 голосов
/ 01 октября 2008

Windows Forms позволяет разрабатывать компоненты, невизуальные элементы которых может иметь конструктор. Встроенные компоненты включают в себя BackgroundWorker, Timer и множество объектов ADO .NET. Это хороший способ обеспечить простую настройку сложного объекта, и он позволяет привязку данных с помощью дизайнера.

Я смотрел на WPF, и, похоже, нет какой-либо концепции компонентов. Я прав насчет этого? Есть какой-то метод создания компонентов (или что-то вроде компонента), который я пропустил?

Я принял ответ Боба, потому что после долгих исследований я чувствую, что модные украшения, вероятно, единственный способ сделать это.

Ответы [ 4 ]

6 голосов
/ 01 октября 2008

По моим собственным наблюдениям, похоже, что Microsoft пытается отказаться от наличия компонентов и подобных вещей в GUI. Я думаю, что WPF пытается ограничить большую часть того, что находится в XAML, вещами с графическим интерфейсом. Связывание данных, я думаю, будет единственным исключением. Я знаю, что стараюсь держать все остальное в коде позади или в отдельных классах или сборках.

Вероятно, не совсем тот ответ, который вы хотели, но это мои 0,02 доллара.

2 голосов
/ 29 сентября 2010

У меня такой же вопрос. Преимущество подобного компоненту механизма заключается в том, что разработчик может добавить его в Blend, настроить его в конструкторе с помощью редактора свойств и использовать привязку данных. Что вы думаете о решении ниже? Это работает.

public class TimerComponent : FrameworkElement
{
    public Timer Timer { get; protected set; }

    public TimerComponent()
    {
        if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
        {
            Visibility = Visibility.Collapsed;
            Timer = new Timer(OnTimerTick, null, Timeout.Infinite, Timeout.Infinite);
        }
    }

    void OnTimerTick(object ignore)
    {
        Dispatcher.BeginInvoke(new Action(RaiseTickEvent));
    }

    #region DueTime Dependency Property

    public int DueTime
    {
        get { return (int)GetValue(DueTimeProperty); }
        set { SetValue(DueTimeProperty, value); }
    }

    public static readonly DependencyProperty DueTimeProperty =
        DependencyProperty.Register("DueTime", typeof(int), typeof(TimerComponent), new UIPropertyMetadata(new PropertyChangedCallback(OnDueTimeChanged)));

    static void OnDueTimeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var target = obj as TimerComponent;
        if (target.Timer != null)
        {
            var newDueTime = (int)e.NewValue;
            target.Timer.Change(newDueTime, target.Period);
        }
    }

    #endregion

    #region Period Dependency Property

    public int Period
    {
        get { return (int)GetValue(PeriodProperty); }
        set { SetValue(PeriodProperty, value); }
    }

    public static readonly DependencyProperty PeriodProperty =
        DependencyProperty.Register("Period", typeof(int), typeof(TimerComponent), new UIPropertyMetadata(new PropertyChangedCallback(OnPeriodChanged)));

    static void OnPeriodChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
    {
        var target = obj as TimerComponent;
        if (target.Timer != null)
        {
            var newPeriod = (int)e.NewValue;
            target.Timer.Change(target.DueTime, newPeriod);
        }
    }

    #endregion

    #region Tick Routed Event

    public static readonly RoutedEvent TickEvent = EventManager.RegisterRoutedEvent(
        "Tick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TimerComponent));

    public event RoutedEventHandler Tick
    {
        add { AddHandler(TickEvent, value); }
        remove { RemoveHandler(TickEvent, value); }
    }

    private void RaiseTickEvent()
    {
        RoutedEventArgs newEventArgs = new RoutedEventArgs(TimerComponent.TickEvent);
        RaiseEvent(newEventArgs);
    }

    #endregion
}

А используется следующим образом.

<StackPanel>
    <lib:TimerComponent Period="{Binding ElementName=textBox1, Path=Text}" Tick="OnTimerTick" />
    <TextBox x:Name="textBox1" Text="1000" />
    <Label x:Name="label1" />
</StackPanel>
1 голос
/ 03 февраля 2009

Вы можете поместить все, что захотите, в словарь ресурсов, включая классы, которые не имеют никакого отношения к Wpf.

Следующий XAML добавляет строку «Hello» непосредственно в окно (фактическая строка, а не элемент управления, который показывает строку), вы можете использовать тот же метод для размещения чего угодно - включая классы, которые вы записываете сами в файл XAML.

<Window  x:Class="MyApp.Window1"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
<Window.Resources>
    <sys:String x:Key="MyString">Hello</sys:String>
</Window.Resources>
</Window>
1 голос
/ 01 октября 2008

Пока что единственный подход, который я вижу, имеет смысл сделать экземпляр класса статическим ресурсом и настроить его из XAML. Это работает, но было бы неплохо, если бы там было что-то вроде панели компонентов дизайнера WinForms, в которой они могли бы жить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...