문제

Windows 양식을 사용하면 디자이너를 가질 수있는 부품, 비 시각 요소를 개발할 수 있습니다. 내장 구성 요소에는 백그라운드 작업자, 타이머 및 많은 ADO .NET 객체가 포함됩니다. 복잡한 객체를 쉽게 구성 할 수있는 좋은 방법이며 디자이너 지원 데이터 바인딩을 가능하게합니다.

나는 WPF를보고 있었고 구성 요소의 개념이있는 것처럼 보이지 않습니다. 내가 이것에 대해 옳습니까? 내가 놓친 구성 요소 (또는 구성 요소와 같은)를 작성하는 방법이 있습니까?

나는 많은 연구 후에 멋진 장식가들이 아마도 이것을하는 유일한 방법이라고 생각하기 때문에 Bob의 대답을 받아 들였습니다.

도움이 되었습니까?

해결책

내 자신의 관찰에서 바로 Microsoft가 GUI에 구성 요소와 유사한 것들을 가지고 있지 않으려 고하는 것처럼 보입니다. WPF는 XAML의 대부분을 엄격하게 GUI 물건으로 제한하려고 시도한다고 생각합니다. 데이터 바인딩 유일한 예외라고 생각합니다. 나는 코드-홀드 또는 별도의 클래스 또는 어셈블리에 다른 모든 것을 유지하려고 노력한다는 것을 알고 있습니다.

아마도 당신이 원하는 대답은 아니지만 내 $ 0.02입니다.

다른 팁

나는 같은 질문이 있습니다. 구성 요소와 같은 메커니즘의 장점은 디자이너가 블렌드로 추가하고 특성 편집기를 사용하여 디자이너에서 구성하고 데이터 바인딩을 사용한다는 것입니다. 아래 솔루션에 대해 어떻게 생각하십니까? 효과가있다.

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>

지금까지, 내가 본 유일한 접근법은 클래스 A 정적 자원의 인스턴스를 만들고 XAML에서 구성하는 것입니다. 이것은 작동하지만 WinForms 디자이너 구성 요소 트레이와 같은 것이 있다면 좋을 것입니다.

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>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top