MAUI:自定义条目
MAUI : Customize an Entry
我是 MAUI 新手,对 Xamarin.Forms
有基本了解
我想在 MAUI 中为 Entry 控件添加底部边框(和边框刻度)。
在 Xamarin.Forms,我们必须创建一个自定义控件,然后为每个平台创建一个渲染器。
在发布此消息之前,我在互联网上进行了研究。它涉及处理程序,我的印象是它只允许进行基本修改(更改背景颜色等)。
我对所有这些信息有点困惑,如果有人能启发我,我将不胜感激。
Customize specific control instances 显示了一个自定义条目的简单示例,它仅针对每个平台自定义一些属性。
我已经开始创建 .Net Maui advanced custom Entry example。到目前为止,请参阅该回购协议。
状态:
- 演示 Windows 上的下划线颜色和粗细。
- 在 Android 上有下划线的开头。
限制(当前):
- 在 Windows 上,一些
Entry
properties
需要映射到包含的文本框。
- 尚未测试
Entry
events
,看看是否需要任何特殊处理。
- Android 下划线无法控制其粗细或颜色。
- 除了 Windows 或 iOS 以外的平台没有实现。
如果你想进一步扩展,google xamarin forms customize entry renderer
platform-specific 代码示例。希望我已经展示了足够多的内容来让大家了解 how/where 添加这样的代码。
在这个时候,做一个高级示例似乎比相应的 Xamarin Forms“自定义渲染器”工作更多。
原因:
- 需要适应 Maui 的处理程序映射方案。可能只需要高级文档和示例。
- 由于
IEntry
和 IEntryHandler
需要的类型,难以扩展现有的 EntryHandler。如何覆盖 PlatformView
的类型??
- 难以复制现有处理程序的功能(以便进行细微更改),因为 built-in 处理程序使用的某些扩展是“内部的”,因此必须复制这些文件。其中提到了其他文件。然后我复制了。并进行了一些更改以避免与现有扩展的歧义冲突。
待定:也许有办法避免我遇到的并发症。
另外可能有我复制的代码,可以省略。
这些是需要完成的步骤:
- 使用所需的附加属性定义 class
MyEntry : Entry
。
- 定义 class
MyEntryHandler
以呈现原生 UI 个对象。
- MauiProgram 中的添加处理程序。
1.使用所需的附加属性定义 class 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。定义 class MyEntryHandler
以呈现为本机 UI 对象。
这是用 partial class
完成的。一个部分是 cross-platform,然后需要为您实现的每个平台使用另一部分。
在我的存储库中,找到 MyEntryHandler.cs
、Windows/MyEntryHandler.Windows.cs
和 Android/MyEntryHandler.Android.cs
。
MyEntryHandler.cs:
这包含 MyEntryHandler 的“映射器”。
// 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)
{
}
我还没有在所有平台文件夹中创建最小部分 classes。在 repo 的 cross-platform MyEntryHandler 中,您会在 #if WINDOWS
中看到代码。目的是不需要将其包装在 #if
中。您还会看到很多注释掉的代码;这样我就可以看到需要在每个平台上实现哪些方法。
MyEntryHandler.Windows.cs:
本质是CreatePlatformView()
。在 Windows 上,我选择实现为包含 TextBox
.
的 Border
(除底部外所有边均为零)
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 处理程序还有许多其他行。这些都是从毛伊岛源复制过来的。需要哪些(如果有的话)待定。如果我想出如何简单地从 Maui 的 EntryHandler 继承,就不需要这些了。但是继承的时候有type
冲突
3: MauiProgram中的AddHandler.
MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(MyEntry), typeof(MyEntryHandler));
})
...
您会在存储库中看到其他 classes 添加到 Maui 项目。这些是从毛伊岛来源复制的。
这些其他 classes 被上面提到的 classes 引用。
希望其他大多数 class 消失,一旦这个主题得到更好的理解。
在 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 新手,对 Xamarin.Forms
有基本了解我想在 MAUI 中为 Entry 控件添加底部边框(和边框刻度)。
在 Xamarin.Forms,我们必须创建一个自定义控件,然后为每个平台创建一个渲染器。
在发布此消息之前,我在互联网上进行了研究。它涉及处理程序,我的印象是它只允许进行基本修改(更改背景颜色等)。
我对所有这些信息有点困惑,如果有人能启发我,我将不胜感激。
Customize specific control instances 显示了一个自定义条目的简单示例,它仅针对每个平台自定义一些属性。
我已经开始创建 .Net Maui advanced custom Entry example。到目前为止,请参阅该回购协议。
状态:
- 演示 Windows 上的下划线颜色和粗细。
- 在 Android 上有下划线的开头。
限制(当前):
- 在 Windows 上,一些
Entry
properties
需要映射到包含的文本框。 - 尚未测试
Entry
events
,看看是否需要任何特殊处理。 - Android 下划线无法控制其粗细或颜色。
- 除了 Windows 或 iOS 以外的平台没有实现。
如果你想进一步扩展,google xamarin forms customize entry renderer
platform-specific 代码示例。希望我已经展示了足够多的内容来让大家了解 how/where 添加这样的代码。
在这个时候,做一个高级示例似乎比相应的 Xamarin Forms“自定义渲染器”工作更多。
原因:
- 需要适应 Maui 的处理程序映射方案。可能只需要高级文档和示例。
- 由于
IEntry
和IEntryHandler
需要的类型,难以扩展现有的 EntryHandler。如何覆盖PlatformView
的类型?? - 难以复制现有处理程序的功能(以便进行细微更改),因为 built-in 处理程序使用的某些扩展是“内部的”,因此必须复制这些文件。其中提到了其他文件。然后我复制了。并进行了一些更改以避免与现有扩展的歧义冲突。
待定:也许有办法避免我遇到的并发症。
另外可能有我复制的代码,可以省略。
这些是需要完成的步骤:
- 使用所需的附加属性定义 class
MyEntry : Entry
。 - 定义 class
MyEntryHandler
以呈现原生 UI 个对象。 - MauiProgram 中的添加处理程序。
1.使用所需的附加属性定义 class 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。定义 class MyEntryHandler
以呈现为本机 UI 对象。
这是用 partial class
完成的。一个部分是 cross-platform,然后需要为您实现的每个平台使用另一部分。
在我的存储库中,找到 MyEntryHandler.cs
、Windows/MyEntryHandler.Windows.cs
和 Android/MyEntryHandler.Android.cs
。
MyEntryHandler.cs:
这包含 MyEntryHandler 的“映射器”。
// 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)
{
}
我还没有在所有平台文件夹中创建最小部分 classes。在 repo 的 cross-platform MyEntryHandler 中,您会在 #if WINDOWS
中看到代码。目的是不需要将其包装在 #if
中。您还会看到很多注释掉的代码;这样我就可以看到需要在每个平台上实现哪些方法。
MyEntryHandler.Windows.cs:
本质是CreatePlatformView()
。在 Windows 上,我选择实现为包含 TextBox
.
Border
(除底部外所有边均为零)
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 处理程序还有许多其他行。这些都是从毛伊岛源复制过来的。需要哪些(如果有的话)待定。如果我想出如何简单地从 Maui 的 EntryHandler 继承,就不需要这些了。但是继承的时候有type
冲突
3: MauiProgram中的AddHandler.
MauiProgram.cs
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMauiHandlers(handlers =>
{
handlers.AddHandler(typeof(MyEntry), typeof(MyEntryHandler));
})
...
您会在存储库中看到其他 classes 添加到 Maui 项目。这些是从毛伊岛来源复制的。
这些其他 classes 被上面提到的 classes 引用。
希望其他大多数 class 消失,一旦这个主题得到更好的理解。
在 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>