Я пытаюсь стилизовать элемент управления Entry для Windows и Android, Я сосредоточусь на Windows, потому что Android, кажется, решена, но я не тестировал ее тщательно, поэтому оставляю этот вопрос на предмет возможного улучшения . Я хочу изменить визуальные состояния BorderThickness и BorderBrush по умолчанию в обычном, PointerOver и Focused для тем Light и Dark.
После некоторых ответов из переполнения стека и самой документации мне удалось получить доступ к свойствам, но не для всех необходимых случаев, например:
Это был бы мой предпочтительный выбор, поскольку я мог бы абстрагироваться в один файл и просто выполнить его в MauiProgram, но он работает только для нормального визуального состояния, так как я не могу получить доступ к VisualStates. GetVisualStateGroups() возвращает пустую коллекцию, поэтому я не смог протестировать остальную часть кода.
Код: Выделить всё
Microsoft.Maui.Handlers.EntryHandler.Mapper.AppendToMapping(nameof(Entry), (handler, view) =>
{
#if ANDROID
AndroidX.AppCompat.Widget.AppCompatEditText androidNativeView = handler.PlatformView;
androidNativeView.SetBackgroundColor(Android.Graphics.Color.Transparent);
#elif WINDOWS
var borderThickness = new Microsoft.UI.Xaml.Thickness(0, 0, 0, 1);
var borderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 175, 175, 175));
var pointerOverBorderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 143, 143, 143));
Microsoft.UI.Xaml.Controls.TextBox windowsNativeView = handler.PlatformView;
windowsNativeView.BorderThickness = borderThickness;
windowsNativeView.BorderBrush = borderBrush;
var visualStateGroups = Microsoft.UI.Xaml.VisualStateManager.GetVisualStateGroups(windowsNativeView);
//focused
var focusedAnimationObjects = visualStateGroups
.FirstOrDefault(g => g.Name == "Focused")?
.States.FirstOrDefault(s => s.Name == "Focused")?
.Storyboard?.Children.OfType();
var borderThicknessAnimation = focusedAnimationObjects?
.FirstOrDefault(a => a.GetType().GetProperty("TargetProperty")?.GetValue(a)?.ToString() == "(UIElement.BorderThickness)");
if (borderThicknessAnimation != null)
{
borderThicknessAnimation.KeyFrames.Clear();
borderThicknessAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame()
{
KeyTime = TimeSpan.Zero,
Value = borderThickness
});
}
var borderBrushAnimation = focusedAnimationObjects?
.FirstOrDefault(a => a.GetType().GetProperty("TargetProperty")?.GetValue(a)?.ToString() == "(UIElement.BorderBrush)");
if (borderBrushAnimation != null)
{
borderBrushAnimation.KeyFrames.Clear();
borderBrushAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame()
{
KeyTime = TimeSpan.Zero,
Value = borderBrush
});
}
//pointerover
var pointerOverBorderBrushAnimation = visualStateGroups
.FirstOrDefault(g => g.Name == "PointerOver")?
.States.FirstOrDefault(s => s.Name == "PointerOver")?
.Storyboard?.Children.OfType()?
.FirstOrDefault(a => a.GetType().GetProperty("TargetProperty")?.GetValue(a)?.ToString() == "(UIElement.BorderBrush)");
if (pointerOverBorderBrushAnimation != null)
{
pointerOverBorderBrushAnimation.KeyFrames.Clear();
pointerOverBorderBrushAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame()
{
KeyTime = TimeSpan.Zero,
Value = pointerOverBorderBrush
});
}
#endif
});
Код: Выделить всё
TextBoxНапример, изменение части Windows следующее не меняет визуальное состояние «В фокусе»:
Код: Выделить всё
var borderThickness = new Microsoft.UI.Xaml.Thickness(0, 0, 0, 1);
var borderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 175, 175, 175));
var pointerOverBorderBrush = new Microsoft.UI.Xaml.Media.SolidColorBrush(Windows.UI.Color.FromArgb(255, 143, 143, 143));
Microsoft.UI.Xaml.Controls.TextBox windowsNativeView = handler.PlatformView;
windowsNativeView.BorderThickness = borderThickness;
windowsNativeView.BorderBrush = borderBrush;
windowsNativeView.GotFocus += (s, e) =>
{
windowsNativeView.BorderThickness = borderThickness;
windowsNativeView.BorderBrush = borderBrush;
};
PS: В данном случае, изменяя состояние сфокусированного визуального изображения, я просто хочу удалить толстое синее подчеркивание.
PS: В данном случае, изменяя состояние сфокусированного визуального элемента, я просто хочу удалить толстое синее подчеркивание. Приведенный выше код должен сохранить тот же стиль, как сфокусированный, так и несфокусированный.
PS: В этом случае я просто хочу удалить толстое синее подчеркивание. em>
Тогда можно воспользоваться менее предпочтительным подходом: удалить часть Windows приведенного выше кода и изменить Platforms/Windows/ App.xaml в включить:
Код: Выделить всё
0,0,0,1
0,0,0,1
В заключение, для первого примера, можем ли мы получить доступ и изменить свойства границы нативного посмотреть на различные визуальные состояния? И я считаю, что должен быть более простой ответ: как я могу изменить тему в части кода WinUI? особенно для этих свойств, которые кажутся черной магией (я считаю, что это просто переопределяет системные идентификаторы для этих свойств, но все же)
Ссылки:
ТАКОЙ ответ, который заложил основу для работы
.Документация по обработчикам Net MauiБиблиотека стилей Microsoft, из которой я получил «волшебство» ключи xaml
Разная ссылка, отличный ответ SO, но это создание совершенно нового элемента управления с полноценными обработчиками и всем этим, мой вопрос в надежде избежать всего этого, у меня есть 1 Запись в моем приложении.
Подробнее здесь: https://stackoverflow.com/questions/793 ... ry-in-maui
Мобильная версия