什么';WinForms组件的WPF等价物是什么?

什么';WinForms组件的WPF等价物是什么?,wpf,winforms,components,Wpf,Winforms,Components,Windows窗体允许您开发组件,即可以使用设计器的非可视元素。内置组件包括BackgroundWorker、Timer和许多ADO.NET对象。这是一种很好的方法,可以提供复杂对象的简单配置,并支持设计器辅助的数据绑定 我一直在看WPF,它似乎没有任何组件的概念。我说的对吗?是否有一些创建组件(或类似组件的东西)的方法是我错过的 我接受了Bob的答案,因为经过大量研究,我觉得花哨的装饰器可能是实现这一点的唯一方法。到目前为止,我认为唯一有意义的方法是将类的实例设置为静态资源,并从XAML配置它

Windows窗体允许您开发组件,即可以使用设计器的非可视元素。内置组件包括BackgroundWorker、Timer和许多ADO.NET对象。这是一种很好的方法,可以提供复杂对象的简单配置,并支持设计器辅助的数据绑定

我一直在看WPF,它似乎没有任何组件的概念。我说的对吗?是否有一些创建组件(或类似组件的东西)的方法是我错过的


我接受了Bob的答案,因为经过大量研究,我觉得花哨的装饰器可能是实现这一点的唯一方法。

到目前为止,我认为唯一有意义的方法是将类的实例设置为静态资源,并从XAML配置它。这是可行的,但如果有类似WinForms designer组件托盘的东西可以放在其中,那就太好了。

根据我自己的观察,微软似乎正试图摆脱GUI中的组件和类似东西。我认为WPF试图将XAML中的大部分内容严格限制为GUI内容。我想数据绑定是唯一的例外。我知道我试图将代码中的大部分其他内容保留在后面或单独的类或程序集中


可能不是您想要的答案,但它是我的$0.02。

您可以在资源字典中放入任何您喜欢的内容,包括与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>

你好

我有同样的问题。类组件机制的优点是,设计器可以将其添加到Blend中,在设计器中使用Properties editor对其进行配置,并使用数据绑定。你认为下面的解决方案如何?它起作用了

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>

winforms中的组件还可以向控件(如工具提示或验证)添加新功能。