如何将 object 作为可绑定 属性 传递给 Xamarin.Forms 自定义控件
How to pass object as bindable property to Xamarin.Forms custom control
如标题所示,我试图将一个人 object 传递给自定义控件,而不是分别传递每个 属性。
所以这个:
<controls:PersonControl
Person="{Binding Person}"
ControlTemplate="{StaticResource PersonControlTemplate}">
</controls:PersonControl>
而不是这个(有效,基于 this 实施)
<controls:PersonControl
Name="{Binding Person.Name}"
Age="{Binding Person.Age}"
ControlTemplate="{StaticResource PersonControlTemplate}">
</controls:PersonControl>
我已经尝试更改后面的 PersonControl 代码上的可绑定 属性 签名,但它不起作用。我实际上只是得到一个空白屏幕。
所以:
1 - 这甚至可能吗(我知道它被称为 bindable 属性 但它也需要 objects 吗?
和
2 - 如果不是,推荐的方法是什么?
我想这样做的原因是这个人 object 可能会随着时间的推移而成长,我宁愿只更新自定义控件而不是消费页面及其视图模型。
更新:
这是 PersonControl 代码:
public partial class PersonControl : ContentView
{
public static readonly BindableProperty PersonProperty = BindableProperty.Create(
nameof(Person),
typeof(Person),
typeof(PersonControl),
string.Empty);
public string Name
{
get { return this.Person.Name; }
}
public Person Person
{
get { return (Person)GetValue(PersonProperty); }
set { SetValue(PersonProperty, value); }
}
public PersonControl()
{
InitializeComponent();
}
}
这里是 PersonControl xaml:
<ContentView.Content>
<StackLayout>
<Label Text="{TemplateBinding Person.Name, Mode=OneWay}"/>
</StackLayout>
</ContentView.Content>
最后是消费页面:
<ContentPage.Resources>
<ControlTemplate x:Key="PersonControlTemplate">
<controls:PersonControl></controls:PersonControl>
</ControlTemplate>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Spacing="10" x:Name="layout">
<controls:PersonControl
Person="{Binding Person}"
ControlTemplate="{StaticResource PersonControlTemplate}"></controls:PersonControl>
</StackLayout>
</ContentPage.Content>
根据 mvvm 模式,人 object 是页面视图模型中的 属性。
预先感谢您的帮助。
更新:我按照这个 tutorial 并尝试用 object 替换可绑定字符串类型,但仍然没有快乐
可以,我用了 Entry
,输入一些文本,然后将文本传输到 ContentView
中的标签。这是 运行 GIF。
首先,我添加了一个名为 PersonName
的 属性,如下面的代码
public partial class PersonControl : ContentView
{
public PersonControl()
{
InitializeComponent();
}
public static BindableProperty PersonNameProperty = BindableProperty.Create(
propertyName: "PersonName",
returnType: typeof(string),
declaringType: typeof(PersonControl),
defaultValue: "",
defaultBindingMode: BindingMode.OneWay);
public string PersonName
{
get { return (string)GetValue(PersonNameProperty); }
set { SetValue(PersonNameProperty, value); }
}
}
那么,这里是关于ContentView
布局的代码。请不要忘记在 ContentView
选项卡中添加 x:Name="ParentControl"
。
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="ParentControl"
x:Class="CustomDemoControl.PersonControl">
<ContentView.Content>
<StackLayout>
<Label Text="{Binding Source={x:Reference ParentControl}, Path=PersonName}"/>
</StackLayout>
</ContentView.Content>
</ContentView>
那我在另一个页面用它。
<StackLayout>
<Entry x:Name="myEntry" Text="1"/>
<local:PersonControl
BindingContext="{x:Reference Name=myEntry}"
PersonName="{Binding Path=Text, StringFormat='Welcome Mr {0}'}"
></local:PersonControl>
</StackLayout>
所以,答案是在可绑定 属性 签名(在自定义控件的 cs 中)中传递默认对象,如下所示:
public static readonly BindableProperty PersonProperty =
BindableProperty.Create(
nameof(Person),
typeof(Person),
typeof(PersonProperty ),
default(Person)); //this was the fix
现在,我错过了这个,因为我没有意识到控件中的错误。它只是没有出现在输出 window 中。谁能指出如何正确全面调试 xamarin.forms 应用程序的方向?或者至少在将来发现这些错误?
谢谢
如标题所示,我试图将一个人 object 传递给自定义控件,而不是分别传递每个 属性。
所以这个:
<controls:PersonControl
Person="{Binding Person}"
ControlTemplate="{StaticResource PersonControlTemplate}">
</controls:PersonControl>
而不是这个(有效,基于 this 实施)
<controls:PersonControl
Name="{Binding Person.Name}"
Age="{Binding Person.Age}"
ControlTemplate="{StaticResource PersonControlTemplate}">
</controls:PersonControl>
我已经尝试更改后面的 PersonControl 代码上的可绑定 属性 签名,但它不起作用。我实际上只是得到一个空白屏幕。
所以: 1 - 这甚至可能吗(我知道它被称为 bindable 属性 但它也需要 objects 吗? 和 2 - 如果不是,推荐的方法是什么?
我想这样做的原因是这个人 object 可能会随着时间的推移而成长,我宁愿只更新自定义控件而不是消费页面及其视图模型。
更新: 这是 PersonControl 代码:
public partial class PersonControl : ContentView
{
public static readonly BindableProperty PersonProperty = BindableProperty.Create(
nameof(Person),
typeof(Person),
typeof(PersonControl),
string.Empty);
public string Name
{
get { return this.Person.Name; }
}
public Person Person
{
get { return (Person)GetValue(PersonProperty); }
set { SetValue(PersonProperty, value); }
}
public PersonControl()
{
InitializeComponent();
}
}
这里是 PersonControl xaml:
<ContentView.Content>
<StackLayout>
<Label Text="{TemplateBinding Person.Name, Mode=OneWay}"/>
</StackLayout>
</ContentView.Content>
最后是消费页面:
<ContentPage.Resources>
<ControlTemplate x:Key="PersonControlTemplate">
<controls:PersonControl></controls:PersonControl>
</ControlTemplate>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout Spacing="10" x:Name="layout">
<controls:PersonControl
Person="{Binding Person}"
ControlTemplate="{StaticResource PersonControlTemplate}"></controls:PersonControl>
</StackLayout>
</ContentPage.Content>
根据 mvvm 模式,人 object 是页面视图模型中的 属性。 预先感谢您的帮助。
更新:我按照这个 tutorial 并尝试用 object 替换可绑定字符串类型,但仍然没有快乐
可以,我用了 Entry
,输入一些文本,然后将文本传输到 ContentView
中的标签。这是 运行 GIF。
首先,我添加了一个名为 PersonName
的 属性,如下面的代码
public partial class PersonControl : ContentView
{
public PersonControl()
{
InitializeComponent();
}
public static BindableProperty PersonNameProperty = BindableProperty.Create(
propertyName: "PersonName",
returnType: typeof(string),
declaringType: typeof(PersonControl),
defaultValue: "",
defaultBindingMode: BindingMode.OneWay);
public string PersonName
{
get { return (string)GetValue(PersonNameProperty); }
set { SetValue(PersonNameProperty, value); }
}
}
那么,这里是关于ContentView
布局的代码。请不要忘记在 ContentView
选项卡中添加 x:Name="ParentControl"
。
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="ParentControl"
x:Class="CustomDemoControl.PersonControl">
<ContentView.Content>
<StackLayout>
<Label Text="{Binding Source={x:Reference ParentControl}, Path=PersonName}"/>
</StackLayout>
</ContentView.Content>
</ContentView>
那我在另一个页面用它。
<StackLayout>
<Entry x:Name="myEntry" Text="1"/>
<local:PersonControl
BindingContext="{x:Reference Name=myEntry}"
PersonName="{Binding Path=Text, StringFormat='Welcome Mr {0}'}"
></local:PersonControl>
</StackLayout>
所以,答案是在可绑定 属性 签名(在自定义控件的 cs 中)中传递默认对象,如下所示:
public static readonly BindableProperty PersonProperty =
BindableProperty.Create(
nameof(Person),
typeof(Person),
typeof(PersonProperty ),
default(Person)); //this was the fix
现在,我错过了这个,因为我没有意识到控件中的错误。它只是没有出现在输出 window 中。谁能指出如何正确全面调试 xamarin.forms 应用程序的方向?或者至少在将来发现这些错误? 谢谢