Pergunta

Windows Forms permite desenvolver componentes, elementos não-visuais que podem ter um designer. Built-in componentes incluem o BackgroundWorker, Timer, e um monte de objetos ADO .NET. É uma boa maneira de fornecer fácil configuração de um objeto complicado, e que permite que os dados assistida pelo designer de ligação.

Eu estive olhando WPF, e não parece que haja qualquer conceito de componentes. Estou certo sobre isso? Existe algum método de criação de componentes (ou algo como um componente) que eu perdi?

Eu aceitei resposta de Bob, porque depois de muita pesquisa eu sinto que Adorners extravagantes são provavelmente a única maneira de fazer isso.

Foi útil?

Solução

Apenas de minhas próprias observações, parece que a Microsoft está tentando mover-se longe de ter componentes e coisas semelhantes na GUI. Acho WPF tenta limitar mais do que está no XAML para coisas estritamente GUI. ligação de dados Eu acho que seria a única exceção. Eu sei que eu tento manter tudo o mais no código-behind ou em classes ou conjuntos separados.

Provavelmente não é exatamente a resposta que queria, mas é o meu $ 0,02.

Outras dicas

Eu tenho a mesma pergunta. A vantagem de um mecanismo componente-como é que o designer pode adicioná-lo no Blend, configurá-lo no designer com o editor Propriedades e ligação de dados de uso. O que você acha da solução abaixo? Ele funciona.

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
}

E é usado como segue.

<StackPanel>
    <lib:TimerComponent Period="{Binding ElementName=textBox1, Path=Text}" Tick="OnTimerTick" />
    <TextBox x:Name="textBox1" Text="1000" />
    <Label x:Name="label1" />
</StackPanel>

Até agora, a única abordagem vejo que sentido marcas é fazer com que uma instância da classe um recurso estático e configure-o de XAML. Isso funciona, mas seria bom se houvesse algo como bandeja de componentes do WinForms designer que estes poderiam viver.

Você pode colocar o que quiser dentro de um dicionário de recursos, incluindo classes que não têm nenhuma relação que assim sempre para o WPF.

A seguir XAML adiciona a string "Olá" diretamente em uma janela (a seqüência real, não um controle que mostra a string), você pode usar o mesmo método para lugar qualquer coisa - incluindo aulas que você escreve-se em um arquivo 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>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top