扩展Avalonia中的按钮控制

时间:2018-10-10 11:29:51

标签: c# xaml avaloniaui

我想要一个AdditionalTextButton,它显然具有附加的text属性。 我的第一个尝试是扩展Avalonia.Controls.Button。这是正确的方法吗?

using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
using System;

namespace VW7OrbMachineAvalonia1.Components.Controls
{

    public class AdditionalTextButton : Button
    {

        /// <summary>
        /// Bottom left displayed Text
        /// </summary>
        public string BottomLeftText
        {
            get { return (string)GetValue(BottomLeftTextProperty); }
            set { SetValue(BottomLeftTextProperty, value); }
        }

        public static readonly StyledProperty<String> BottomLeftTextProperty =
            AvaloniaProperty.Register<AdditionalTextButton, String>("BottomLeftText");
    }
}

然后我要使用AdditionalTextButton:

  <vwaui:AdditionalTextButton
          Width="100"
          Height="100"
          Content="Content"
          BottomLeftText="BottomLeft">
  </vwaui:AdditionalTextButton>

但是没有显示AdditionalTextButton。

之后,如果可以的话,我想将样式应用于AdditionalTextButton

<Styles xmlns="https://github.com/avaloniaui"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:vwaui="clr-namespace:VW7OrbMachineAvalonia1.Components.Controls;assembly=VW7OrbMachineAvalonia1">

  <Style x:Key="additionalTextButtonStyle" Selector="is vwaui:Additionaltextbutton">
    <Setter Property="Button.FontSize" Value="22"/>
    <Setter Property="Button.Template">
      <Setter.Value>
        <ControlTemplate>
          <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                <TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom"  TextWrapping="Wrap" Text="{TemplateBinding BottomLeftText}"/>
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"  TextWrapping="Wrap" Text="{TemplateBinding Content}"/>
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Styles>

但是使用这种样式,我遇到了以下异常:

Portable.Xaml.XamlObjectWriterException: Set value of member '{clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls}ContentControl.Content' threw an exception ---> System.ArgumentException: Property 'Template not registered on 'Avalonia.Controls.Grid
   at Avalonia.AvaloniaObject.ThrowNotRegistered(AvaloniaProperty p)
   at Avalonia.AvaloniaObject.Bind(AvaloniaProperty property, IObservable`1 source, BindingPriority priority)
   at Avalonia.Styling.Style.Attach(IStyleable control, IStyleHost container)
   at Avalonia.Styling.Styles.Attach(IStyleable control, IStyleHost container)
   at Avalonia.Styling.Styles.Attach(IStyleable control, IStyleHost container)
   at Avalonia.Styling.Styler.ApplyStyles(IStyleable control, IStyleHost styleHost)
   at Avalonia.Styling.Styler.ApplyStyles(IStyleable control, IStyleHost styleHost)
   at Avalonia.Controls.Control.OnAttachedToLogicalTreeCore(LogicalTreeAttachmentEventArgs e)
   at Avalonia.Controls.Control.Avalonia.Controls.ISetLogicalParent.SetParent(ILogical parent)
   at Avalonia.Controls.Control.SetLogicalParent(IEnumerable`1 children)
   at Avalonia.Collections.AvaloniaList`1.NotifyAdd(IList t, Int32 index)
   at System.Reactive.Observer`1.OnNext(T value)
   at Avalonia.AvaloniaObject.RaisePropertyChanged(AvaloniaProperty property, Object oldValue, Object newValue, BindingPriority priority)
   at Avalonia.AvaloniaObject.Avalonia.IPriorityValueOwner.Changed(PriorityValue sender, Object oldValue, Object newValue)
   at Avalonia.Utilities.DeferredSetter`2.<>c__DisplayClass9_0`1.<SetAndNotify>b__0(Action notification)
   at Avalonia.PriorityValue.UpdateCore(ValueTuple`2 update, ValueTuple`2& backing, Action`1 notify)
   at Avalonia.Utilities.DeferredSetter`2.SetAndNotify[TValue](TProperty property, TValue& backing, SetterDelegate`1 setterCallback, TSetRecord value)
   at Avalonia.PriorityValue.UpdateValue(Object value, Int32 priority)
   at Avalonia.AvaloniaObject.SetStyledValue(AvaloniaProperty property, Object value, BindingPriority priority)
   at Portable.Xaml.XamlObjectWriterInternal.SetValue(XamlMember member, Object target, Object value)
   --- End of inner exception stack trace ---
   at Portable.Xaml.XamlObjectWriterInternal.SetValue(XamlMember member, Object target, Object value)
   at Portable.Xaml.XamlWriterInternalBase.WriteEndMember()
   at Portable.Xaml.XamlServices.Transform(XamlReader xamlReader, XamlWriter xamlWriter, Boolean closeWriter)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.LoadFromReader(XamlReader reader, AvaloniaXamlContext context)
   at Avalonia.Markup.Xaml.AvaloniaXamlLoaderPortableXaml.Load(Stream stream, Object rootInstance, Uri uri)
   at Avalonia.DesignerSupport.DesignWindowLoader.LoadDesignerWindow(String xaml, String assemblyPath)
   at Avalonia.DesignerSupport.Remote.RemoteDesignerEntryPoint.<>c__DisplayClass17_0.<OnTransportMessage>b__0()

总的来说,我对扩展控件感兴趣,在Avalonia中这是这样做的方法吗? 我无法通过DocumentationSource来获得它。 希望您能为我解释一下,并指出正确的方向。

[编辑] 好吧,我将此行添加到AdditionalTextButton.cs:

Type IStyleable.StyleKey => typeof(Button);

现在,AdditionalTextButton可见,但是与布局中的其他Button相比,其样式有所不同。并且additionalTextButtonStyle也不适用于AdditionalTextButton。如果我将以上行中的“按钮”更改为“ AdditionalTextButton”,则AdditionalTextButton将不再可见。 在那之后,我给了AdditionalTextButton一个styleClass,并强制样式将被应用,但是所有的Button不再可见。我不了解这种行为。

[编辑2] 将StyleKey设置为typeOf(AdditionalTextButton),AdditionaltextbuttonStyle将正确应用。但是现在,应该应用于所有Button的另一种Style不适用于AdditionalTextButton。我将为此发布另一个问题。

0 个答案:

没有答案