如何检测视觉元素内置属性的变化? - Xamarin 表格
How to detect changes to a visual element's built-in properties? - Xamarin Forms
我有一个 class ImageButton: Grid 并且想检测其 IsEnabled 属性 的变化.有基于事件的方法吗?
PropertyChanged 事件似乎与此处无关。
.NET 有 IsEnabledChanged 但这似乎也不适用。
背景:我的 class 实现了一个覆盖有文本的可点击图像,充当按钮。它是一个单单元格网格,其中包含一个覆盖有标签的图像。当禁用 ImageButton 对象时,我需要降低标签和图像的不透明度。当然,我可以简单地添加一个 属性 来执行此操作,但随后无法轻松地将 class 用作使用 Button 的现有代码的插件。
旁注:令人费解的是 Button 不提供背景图像 属性 - 这么多开发者一定需要它。
您可以简单地覆盖父控件OnPropertyChanged
以更新内部控件:
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if(propertyName == nameof(IsEnabled))
{
//update controls here
...
}
}
但我宁愿建议您 在将内部控件的 Opacity
绑定到父控件的 IsEnabled
属性 时使用转换器。
例如,如果您在 C# 中定义了自定义控件,则可以将绑定定义为:
public class ImageButton : Grid
{
private static readonly BooleanToOpacityConverter _converter = new BooleanToOpacityConverter();
public ImageButton()
{
var label = new Label { Text = "ImageButton" };
var image = new Image { Source = ImageSource.FromFile("icon.png") };
// add binding to Opacity using IsEnabled from parent
label.SetBinding(OpacityProperty, new Binding("IsEnabled", converter: _converter, source: this));
image.SetBinding(OpacityProperty, new Binding("IsEnabled", converter: _converter, source: this));
ColumnDefinitions = new ColumnDefinitionCollection { new ColumnDefinition(), new ColumnDefinition() };
SetColumn(label, 1);
Children.Add(label);
Children.Add(image);
}
}
或者,如果您使用的是基于 XAML 的自定义控件,您可以将绑定分配为:
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:UpdateSourceTriggerApp"
x:Name="_parent"
x:Class="UpdateSourceTriggerApp.ImageButton2">
<Grid.Resources>
<ResourceDictionary>
<local:BooleanToOpacityConverter x:Key="_converter" />
</ResourceDictionary>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="icon.png" Opacity="{Binding Source={x:Reference _parent}, Path=IsEnabled, Converter={StaticResource _converter}}" />
<Label Text="ImageButton2" Grid.Column="1" Opacity="{Binding Source={x:Reference _parent}, Path=IsEnabled, Converter={StaticResource _converter}}" />
</Grid>
示例转换器如下所示:
public class BooleanToOpacityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var isEnabled = (value == null) ? false : (bool)value;
return isEnabled ? 1 : 0.5;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我有一个 class ImageButton: Grid 并且想检测其 IsEnabled 属性 的变化.有基于事件的方法吗?
PropertyChanged 事件似乎与此处无关。
.NET 有 IsEnabledChanged 但这似乎也不适用。
背景:我的 class 实现了一个覆盖有文本的可点击图像,充当按钮。它是一个单单元格网格,其中包含一个覆盖有标签的图像。当禁用 ImageButton 对象时,我需要降低标签和图像的不透明度。当然,我可以简单地添加一个 属性 来执行此操作,但随后无法轻松地将 class 用作使用 Button 的现有代码的插件。
旁注:令人费解的是 Button 不提供背景图像 属性 - 这么多开发者一定需要它。
您可以简单地覆盖父控件OnPropertyChanged
以更新内部控件:
protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if(propertyName == nameof(IsEnabled))
{
//update controls here
...
}
}
但我宁愿建议您 在将内部控件的 Opacity
绑定到父控件的 IsEnabled
属性 时使用转换器。
例如,如果您在 C# 中定义了自定义控件,则可以将绑定定义为:
public class ImageButton : Grid
{
private static readonly BooleanToOpacityConverter _converter = new BooleanToOpacityConverter();
public ImageButton()
{
var label = new Label { Text = "ImageButton" };
var image = new Image { Source = ImageSource.FromFile("icon.png") };
// add binding to Opacity using IsEnabled from parent
label.SetBinding(OpacityProperty, new Binding("IsEnabled", converter: _converter, source: this));
image.SetBinding(OpacityProperty, new Binding("IsEnabled", converter: _converter, source: this));
ColumnDefinitions = new ColumnDefinitionCollection { new ColumnDefinition(), new ColumnDefinition() };
SetColumn(label, 1);
Children.Add(label);
Children.Add(image);
}
}
或者,如果您使用的是基于 XAML 的自定义控件,您可以将绑定分配为:
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:UpdateSourceTriggerApp"
x:Name="_parent"
x:Class="UpdateSourceTriggerApp.ImageButton2">
<Grid.Resources>
<ResourceDictionary>
<local:BooleanToOpacityConverter x:Key="_converter" />
</ResourceDictionary>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="icon.png" Opacity="{Binding Source={x:Reference _parent}, Path=IsEnabled, Converter={StaticResource _converter}}" />
<Label Text="ImageButton2" Grid.Column="1" Opacity="{Binding Source={x:Reference _parent}, Path=IsEnabled, Converter={StaticResource _converter}}" />
</Grid>
示例转换器如下所示:
public class BooleanToOpacityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var isEnabled = (value == null) ? false : (bool)value;
return isEnabled ? 1 : 0.5;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}