我是 MAUI 新手,具有 Xamarin.Forms 的基本知识
我想向 MAUI 中的 Entry 控件添加底部边框(和边框刻度)。
在 Xamarin.Forms 上,我们必须创建一个自定义控件,然后为每个平台创建一个渲染器。
在发布此消息之前,我在互联网上进行了研究。它涉及处理程序,我的印象是它只允许基本修改(更改背景颜色等......)。
我对所有这些信息有点困惑,如果有人能启发我,我将不胜感激。
Too*_*eve 27
自定义特定控件实例显示了自定义条目的一个简单示例,该示例仅自定义每个平台的一些属性。
我已经开始创建一个.Net Maui 高级自定义条目示例。请参阅该存储库以了解迄今为止的实施情况。
地位:
限制(当前):
Entry properties需要映射到包含的 TextBox。Entry events,看看是否需要任何特殊处理。如果您希望进一步扩展,请搜索xamarin forms customize entry renderer特定于平台的代码示例。希望我已经展示了足够的内容来让大家了解如何/在哪里添加此类代码。
此时,做一个高级示例似乎比相应的 Xamarin Forms“自定义渲染器”需要更多工作。
理由:
IEntry和所需的类型,难以扩展现有的 EntryHandler IEntryHandler。如何覆盖PlatformView??的类型TBD:也许有一种方法可以避免我遇到的并发症。
另外,可能有我复制的代码,可以省略。
这些是需要完成的步骤:
MyEntry : Entry具有所需附加属性的类。MyEntryHandler要呈现到本机 UI 对象的类。1. 定义MyEntry : Entry具有所需附加属性的类。
在这里,我们添加UnderlineColor和UnderlineThickness。
public class MyEntry : Entry
{
    /// <summary>
    /// Color and Thickness of bottom border.
    /// </summary>
    public static BindableProperty UnderlineColorProperty = BindableProperty.Create(
            nameof(UnderlineColor), typeof(Color), typeof(MyEntry), Colors.Black);
    public Color UnderlineColor
    {
        get => (Color)GetValue(UnderlineColorProperty);
        set => SetValue(UnderlineColorProperty, value);
    }
    public static BindableProperty UnderlineThicknessProperty = BindableProperty.Create(
            nameof(UnderlineThickness), typeof(int), typeof(MyEntry), 0);
    public int UnderlineThickness
    {
        get => (int)GetValue(UnderlineThicknessProperty);
        set => SetValue(UnderlineThicknessProperty, value);
    }
    public MyEntry()
    {
    }
}
2. 定义MyEntryHandler要呈现到本机 UI 对象的类。
这是通过partial class. 一部分是跨平台的,然后需要针对您实现的每个平台的另一部分。
在我的存储库中,找到MyEntryHandler.cs、Windows/MyEntryHandler.Windows.cs和Android/MyEntryHandler.Android.cs。
MyEntryHandler.cs:
其中包含 MyEntryHandler 的“Mapper”。
    // Cross-platform partial of class. See Maui repo maui\src\Core\src\Handlers\Entry\EntryHandler.cs
    public partial class MyEntryHandler : IMyEntryHandler //: EntryHandler
    {
        // static c'tor.
        static MyEntryHandler()
        {
            // TBD: Fill MyMapper here by copying from Entry.Mapper, then add custom ones defined in MyEntry?
        }
        //public static IPropertyMapper<IEntry, IEntryHandler> MyMapper => Mapper;
        public static IPropertyMapper<IEntry, MyEntryHandler> MyMapper = new PropertyMapper<IEntry, MyEntryHandler>(ViewMapper)
        {
            // From Entry.
            [nameof(IEntry.Background)] = MapBackground,
            [nameof(IEntry.CharacterSpacing)] = MapCharacterSpacing,
            [nameof(IEntry.ClearButtonVisibility)] = MapClearButtonVisibility,
            [nameof(IEntry.Font)] = MapFont,
            [nameof(IEntry.IsPassword)] = MapIsPassword,
            [nameof(IEntry.HorizontalTextAlignment)] = MapHorizontalTextAlignment,
            [nameof(IEntry.VerticalTextAlignment)] = MapVerticalTextAlignment,
            [nameof(IEntry.IsReadOnly)] = MapIsReadOnly,
            [nameof(IEntry.IsTextPredictionEnabled)] = MapIsTextPredictionEnabled,
            [nameof(IEntry.Keyboard)] = MapKeyboard,
            [nameof(IEntry.MaxLength)] = MapMaxLength,
            [nameof(IEntry.Placeholder)] = MapPlaceholder,
            [nameof(IEntry.PlaceholderColor)] = MapPlaceholderColor,
            [nameof(IEntry.ReturnType)] = MapReturnType,
            [nameof(IEntry.Text)] = MapText,
            [nameof(IEntry.TextColor)] = MapTextColor,
            [nameof(IEntry.CursorPosition)] = MapCursorPosition,
            [nameof(IEntry.SelectionLength)] = MapSelectionLength,
            // From MyEntry
            [nameof(MyEntry.UnderlineThickness)] = MapUnderlineThickness
        };
        // TBD: What is this for? Cloned one on Entry.
        private static void MapUnderlineThickness(MyEntryHandler arg1, IEntry arg2)
        {
        }
        public MyEntryHandler() : base(MyMapper)
        {
        }
我尚未在所有平台文件夹中创建最小部分类。在存储库的跨平台 MyEntryHandler 中,您将看到#if WINDOWS. 目的是这不需要包含在#if. 你还会看到很多被注释掉的代码;这样我就可以了解需要在每个平台上实现哪些方法。
MyEntryHandler.Windows.cs:
本质是CreatePlatformView()。在 Windows 上,我选择实现为Border包含TextBox.
        protected override PlatformView CreatePlatformView()
        {
            var myentry = VirtualView as MyEntry;
            var textbox = new MauiPasswordTextBox
            {
                // From EntryHandler.
                IsObfuscationDelayed = s_shouldBeDelayed
                // TODO: pass some entry properties through to textbox?
            };
            MauiColor color = myentry != null
                    ? myentry.UnderlineColor
                    : MyEntry.UnderlineColorProperty.DefaultValue as MauiColor;
            int thickness = myentry != null
                    ? myentry.UnderlineThickness
                    : (int)MyEntry.UnderlineThicknessProperty.DefaultValue;
            var border = new Border
            {
                Child = textbox,
                BorderBrush = color.ToPlatform(),
                BorderThickness = new Thickness(0, 0, 0, thickness)
            };
            return border;
        }
Windows Handler 还有许多其他行。这些都是从毛伊岛来源复制的。待定需要其中哪些(如果有)。如果我知道如何简单地从 Maui 的 EntryHandler 继承,那么就不需要这些了。type但我继承时发生了冲突。
3:在MauiProgram中添加Handler。
MauiProgram.cs
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureMauiHandlers(handlers =>
            {
                handlers.AddHandler(typeof(MyEntry), typeof(MyEntryHandler));
            })
        ...
您将在存储库中看到添加到 Maui 项目中的其他类。这些是从毛伊岛来源复制的。
这些其他类由上面提到的类引用。
希望一旦这个主题得到更好的理解,其他大部分课程都会消失。
在 Windows 上,AppShell + MainPage 带有两个 MyEntry。一种是带下划线和彩色的。
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:myviews="clr-namespace:MauiCustomEntryHandler"
             x:Class="MauiCustomEntryHandler.MainPage">
             
    <ScrollView>
        <VerticalStackLayout 
                WidthRequest="500" HeightRequest="400"
                Spacing="25" Padding="30,0" BackgroundColor="LightBlue"
                HorizontalOptions="Center" VerticalOptions="Center">
            <Label Text="Hello, Maui!" FontSize="24" HorizontalOptions="Center" />
            <myviews:MyEntry Text="test" FontSize="20" UnderlineThickness="8"
                 UnderlineColor="Purple" BackgroundColor="HotPink" />
            <myviews:MyEntry UnderlineThickness="0" BackgroundColor="LightGray" />
        </VerticalStackLayout>
    </ScrollView>
 
</ContentPage>
如果有人因为(看似)简单的需要更改下划线颜色而登陆此页面,请继续阅读。下面的解决方案只需要几行代码,适用于所有使用突出显示/强调色的 MAUI 控件。
接受的回复似乎是关于如何自定义 MAUI 控件的通用描述的有价值的教程(这再次对应于可能有点通用的原始问题的标题)。然而,如果颜色行为是您唯一的目标,那就完全是矫枉过正了。
MAUI 实现基于操作系统个性化方案。不幸的是,似乎无法在所有平台的一个地方以通用方式覆盖它,但可以在特定于平台的层上控制它。
我最终得到的只是修改一个文件,即 ./Platforms/Windows/App.xaml:
    <maui:MauiWinUIApplication.Resources>
        <ResourceDictionary>
            <Color x:Key="Primary">#500073</Color>
            <StaticResource x:Key="SystemAccentColorDark1" ResourceKey="Primary"/>
            <StaticResource x:Key="SystemAccentColorDark2" ResourceKey="Primary"/>
            <StaticResource x:Key="SystemAccentColorDark3" ResourceKey="Primary"/>
            <StaticResource x:Key="SystemAccentColorLight1" ResourceKey="Primary"/>
            <StaticResource x:Key="SystemAccentColorLight2" ResourceKey="Primary"/>
            <StaticResource x:Key="SystemAccentColorLight3" ResourceKey="Primary"/>
        </ResourceDictionary>
    </maui:MauiWinUIApplication.Resources>
这样,您的颜色将覆盖操作系统系统之一,并且据我猜测,这将修改给定平台上使用此强调色的所有控件的行为。
尽管我的 Windows 设置显示蓝色作为当前的强调色:
最初,我尝试修改通用 ./Resources/Styles/Colors.xaml 文件,希望立即覆盖所有平台上的此行为,但这似乎不起作用。希望 MAUI 团队有一天能够实现通用行为。
| 归档时间: | 
 | 
| 查看次数: | 24138 次 | 
| 最近记录: |