根据多个属性创建 BindableProperty
Create a BindableProperty depending on multiple properties
我正在尝试将 UI 元素绑定到不同的模型属性 A
、B
和 AB
。前两个属性 A
和 B
由两个滑块控制。第三个属性AB
是A
和B
之和。对于这三个属性中的每一个,都有一个显示其值的标签。
现在,如果我移动其中一个滑块,相应的标签会更新其 Text
。但是组合 属性 AB
的标签没有更新。可能没有触发 "property changed" 事件,因为 AB
.
没有 setter
是否有可能绑定到这样的 "aggregated" 属性?
这是包含属性 A
、B
和 AB
的可绑定对象:
public class Settings: BindableObject
{
public static readonly BindableProperty AProperty = BindableProperty.Create<Settings, double>(p => p.A, 0);
public static readonly BindableProperty BProperty = BindableProperty.Create<Settings, double>(p => p.B, 0);
public static readonly BindableProperty ABProperty = BindableProperty.Create<Settings, double>(p => p.AB, 0);
public double A {
get{ return (double)GetValue(AProperty); }
set{ SetValue(AProperty, (double)value); }
}
public double B {
get{ return (double)GetValue(BProperty); }
set{ SetValue(BProperty, (double)value); }
}
public double AB {
get{ return A + B; }
}
}
这是包含滑块和三个标签的页面:
public class App : Application
{
public App()
{
var settings = new Settings();
var sliderA = new Slider();
sliderA.ValueChanged += (sender, e) => settings.A = e.NewValue;
var sliderB = new Slider();
sliderB.ValueChanged += (sender, e) => settings.B = e.NewValue;
var labelA = new Label{ BindingContext = settings };
labelA.SetBinding(Label.TextProperty, "A");
var labelB = new Label{ BindingContext = settings };
labelB.SetBinding(Label.TextProperty, "B");
var labelAB = new Label{ BindingContext = settings };
labelAB.SetBinding(Label.TextProperty, "AB");
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = { sliderA, sliderB, labelA, labelB, labelAB },
},
};
}
}
这是 运行ning 应用程序在 iOS 上的样子:
最后一个标签应显示前两个数字的总和。
编辑:
不知为什么我不会写
public static readonly BindableProperty ABProperty =
BindableProperty.Create<Settings, double>(p => p.A + p.B, 0);
但这会产生 运行 时间错误 "System.TypeInitializationException: An exception was thrown by the type initializer for AggregatedBindablePropertyMnml.Settings ---> System.Exception: getter must be a MemberExpression"
根据 Taekahn 的建议(在 A 和 B 的 setter 内更新 AB),我提出了以下解决方案。
通过覆盖 OnPropertyChanged
方法并设置 ABProperty
,绑定的标签文本也会更新。与单独修改每个 setter 相比,这种方式我们只需要在一个地方修改 Settings
class。
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
SetValue(ABProperty, A + B);
}
现在两个滑块都会影响第三个标签:
我正在尝试将 UI 元素绑定到不同的模型属性 A
、B
和 AB
。前两个属性 A
和 B
由两个滑块控制。第三个属性AB
是A
和B
之和。对于这三个属性中的每一个,都有一个显示其值的标签。
现在,如果我移动其中一个滑块,相应的标签会更新其 Text
。但是组合 属性 AB
的标签没有更新。可能没有触发 "property changed" 事件,因为 AB
.
是否有可能绑定到这样的 "aggregated" 属性?
这是包含属性 A
、B
和 AB
的可绑定对象:
public class Settings: BindableObject
{
public static readonly BindableProperty AProperty = BindableProperty.Create<Settings, double>(p => p.A, 0);
public static readonly BindableProperty BProperty = BindableProperty.Create<Settings, double>(p => p.B, 0);
public static readonly BindableProperty ABProperty = BindableProperty.Create<Settings, double>(p => p.AB, 0);
public double A {
get{ return (double)GetValue(AProperty); }
set{ SetValue(AProperty, (double)value); }
}
public double B {
get{ return (double)GetValue(BProperty); }
set{ SetValue(BProperty, (double)value); }
}
public double AB {
get{ return A + B; }
}
}
这是包含滑块和三个标签的页面:
public class App : Application
{
public App()
{
var settings = new Settings();
var sliderA = new Slider();
sliderA.ValueChanged += (sender, e) => settings.A = e.NewValue;
var sliderB = new Slider();
sliderB.ValueChanged += (sender, e) => settings.B = e.NewValue;
var labelA = new Label{ BindingContext = settings };
labelA.SetBinding(Label.TextProperty, "A");
var labelB = new Label{ BindingContext = settings };
labelB.SetBinding(Label.TextProperty, "B");
var labelAB = new Label{ BindingContext = settings };
labelAB.SetBinding(Label.TextProperty, "AB");
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = { sliderA, sliderB, labelA, labelB, labelAB },
},
};
}
}
这是 运行ning 应用程序在 iOS 上的样子:
最后一个标签应显示前两个数字的总和。
编辑:
不知为什么我不会写
public static readonly BindableProperty ABProperty =
BindableProperty.Create<Settings, double>(p => p.A + p.B, 0);
但这会产生 运行 时间错误 "System.TypeInitializationException: An exception was thrown by the type initializer for AggregatedBindablePropertyMnml.Settings ---> System.Exception: getter must be a MemberExpression"
根据 Taekahn 的建议(在 A 和 B 的 setter 内更新 AB),我提出了以下解决方案。
通过覆盖 OnPropertyChanged
方法并设置 ABProperty
,绑定的标签文本也会更新。与单独修改每个 setter 相比,这种方式我们只需要在一个地方修改 Settings
class。
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
SetValue(ABProperty, A + B);
}
现在两个滑块都会影响第三个标签: