Можно ли получить цвет фона элемента управления из свойства ViewModel?
Цель состоит в том, чтобы иметь возможность изменять цвет Border
или Button
в зависимости от действий пользователя. Поскольку я использую подход MVVM, в идеале я просто устанавливаю цвет фона своего элемента управления через свойство в моей модели представления.
Я пробовал следующее, но это не сработало:
<Border
BackgroundColor = "{Binding MyBorderBackgroundColor}">
<Label Text=“Hello World” />
</Border>
В моей модели представления я использую свойство string
и устанавливаю для него либо имя цвета, например Red
, либо шестнадцатеричное значение, например #FF0000
. У меня есть метод Init()
, который я вызываю из OnAppearing()
и устанавливаю значение — см. ниже:
[ObservableProperty]
string myBorderBackgroundColor;
...
public void Init()
{
MyBorderBackgroundColor = "Red"; // Or Hex value => MyBorderBackgroundColor = "#FF0000";
}
Приложение просто игнорирует настройку цвета и по умолчанию использует фон страницы. Нет ошибки, но просто не используется значение, установленное через свойство модели представления.
Какие-либо предложения?
Приложение просто игнорирует это. Ошибки нет, но не использует. Я обновил исходный пост с более подробной информацией.
Почему вы хотите определить цвета в ViewModel? Вы не можете использовать триггеры? Если вам нужно установить цвета внутри ViewModel, вы можете использовать тип Color
вместо string
: [ObservableProperty] Color myBorderBackgroundColor;
@Sam Кстати, в вашем примере кода это должно быть BackgroundColor = "{Binding MyBorderBackgroundColor}"
, вы забыли там кавычки
Вы можете использовать MyBorderBackgroundColor=Color.FromHex("#2B0B98")
или MyBorderBackgroundColor = Colors.Yellow
и тому подобное.
Прежде всего, вам нужно убедиться, что привязка настроена правильно с использованием двойных кавычек:
<Border
BackgroundColor = "{Binding MyBorderBackgroundColor}">
<Label Text=“Hello World” />
</Border>
Затем я бы рекомендовал использовать тип Color
в ViewModel вместо string
, поскольку между этими типами нет неявного преобразования. Вот как я делаю это и в своих собственных приложениях.
Таким образом, вы можете изменить свой код на следующий и определить цвет различными способами (список не является окончательным):
[ObservableProperty]
string myBorderBackgroundColor;
//...
public void Init()
{
// use hex value
MyBorderBackgroundColor = Color.FromArgb("#FF0000");
// parse string
MyBorderBackgroundColor = Color.Parse("Red");
// use RGB
MyBorderBackgroundColor = Color.FromRgb(255,0,0);
// use named color
MyBorderBackgroundColor = Colors.Red;
//...
}
Вы можете найти больше информации о цветах в официальной документации.
Ваше резервное свойство — это string
, хотя оно должно быть Color
. Однако я понимаю, что вы думаете, что это работает, потому что в XAML вы можете просто добавить к нему строку.
Чтобы понять, почему это работает в XAML, а не в коде, нам нужно узнать о TypeConverter
. Поскольку XAML может содержать только строки, нам нужно найти способ преобразовать эту строку в тип, который действительно можно использовать. С TypeConverter
мы делаем именно это.
К объекту, где мы ожидаем, что люди будут использовать строку в XAML, но все еще ожидаем желаемого результата, мы добавляем этот атрибут, вот он для Color:
[TypeConverter(typeof(Converters.ColorTypeConverter))]
public class Color
{
/// The class
}
Вот полная реализацияColorTypeConverter
, если вам интересно.
Это означает, что когда синтаксический анализатор XAML находит это свойство и соответствующее (строковое) значение, он сначала вызовет это TypeConverter
, и это приведет к конкретному типу, в нашем случае Color
, который будет использоваться.
Когда вы делаете привязку, как вы делаете, TypeConverter
не вызывается, и, таким образом, теперь мы привязываем строковое значение к свойству, которое ожидает объект Color
и, следовательно: не работает.
Чтобы это исправить, измените свойство поддержки на Color
и инициализируйте его как таковое.
[ObservableProperty]
Color myBorderBackgroundColor;
// ...
public void Init()
{
MyBorderBackgroundColor = Colors.Red; // Or Hex value => MyBorderBackgroundColor = Color.FromArgb("#FF0000");
}
Ваш XAML содержит небольшую ошибку без кавычек вокруг привязки. Не уверен, что это в вашем реальном коде, но просто чтобы быть уверенным. Убедитесь, что значение BackgroundColor
заключено в кавычки, например:
<Border
BackgroundColor = "{Binding MyBorderBackgroundColor}">
<Label Text = "Hello World" />
</Border>
Определить «не сработало» какие-либо ошибки? Кроме того, как выглядит ваше резервное имущество?