В Xamarin.Forms я хотел бы привязать код за свойством к метке в XAML.
Я нашел много ответов и веб-страниц по этой теме, но все они охватывают более сложные сценарии.
Это моя страница XAML:
<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local = "clr-namespace:TrackValigie"
x:Class = "TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text = "{Binding ?????????}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
И это код:
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
this.LblText = "Ciao!!";
base.OnAppearing();
}
}
Я хотел бы привязать свойство «LblText» к метке только с использованием XAML, то есть без установки привязки или контекста привязки в исходном коде.
Это возможно?





ваша страница должна будет реализовать INotifyPropertyChanged, но синтаксис привязки должен быть просто
<ContentPage x:Name = "MyPage" ... />
...
<Label BindingContext = "{x:Reference Name=MyPage}" Text = "{Binding LblText}" />
BindingContext = "{x: Reference MyPage}" в качестве альтернативы
ПРИМЕЧАНИЕ. Этот ответ удобен, если Label НЕ требует привязки каких-либо атрибутов к виртуальной машине. Если вы можете добавить будущие атрибуты привязки к той же метке, но эти новые атрибуты необходимо привязать к виртуальной машине (а не к выделенному коду), см. ответ Горота, который связывает ТОЛЬКО атрибут Text с выделенным кодом.
Вам необходимо установить x: Name для ContentPage, как указано в ответе Джейсона.
<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local = "clr-namespace:TrackValigie"
x:Class = "TrackValigie.SelViaggioPage"
x:Name = "MyControl"/>
Вместо использования BindingContext вы можете использовать ElementName
<TextBlock Text = "{Binding ElementName=TestControl,Path=StudentName}"/>
Синтаксис XAML Xamarin.Forms: <TextBlock Text = "{Binding Source = {Reference TestControl}, Path=StudentName}"/>
BindingContext = this; в код позади файла.XAML
<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local = "clr-namespace:TrackValigie"
x:Class = "TrackValigie.SelViaggioPage">
<ContentPage.Content>
<StackLayout>
<Label Text = "{Binding LblText}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Код позади
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class SelViaggioPage : ContentPage
{
private string _lblText;
public string LblText
{
get
{
return _lblText;
}
set
{
_lblText = value;
OnPropertyChanged();
}
}
public SelViaggioPage()
{
InitializeComponent();
BindingContext = this;
}
protected override void OnAppearing()
{
base.OnAppearing();
this.LblText = "Ciao!!";
}
}
Или, если вы не хотите менять контекст привязки для всего элемента управления, используйте следующее:
<?xml version = "1.0" encoding = "utf-8" ?>
<ContentPage xmlns = "http://xamarin.com/schemas/2014/forms"
xmlns:x = "http://schemas.microsoft.com/winfx/2009/xaml"
x:Name = "this"
x:Class = "SomePage">
<ContentPage.Content>
<StackLayout>
<Label Text = "{Binding SomeProp, Source = {x:Reference this}}" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Думаю, это самый ценный ответ. В современном приложении, основанном на шаблоне MVVM, вы почти никогда не будете выполнять привязку к исходному коду элемента управления и не хотите менять местами реальный текст данных (ViewModel). Я искал WPF-эквивалент {Binding ElementName = this, Path = BlaBla}, и вот он. Это также работает в Xamarin ContentView.
См. Также ранее принятый ответ. Принятый ответ удобен, если Label требует привязки несколько к элементам кода программной части и НЕ требует каких-либо привязок к значениям в виртуальной машине. ЭТОТ ответ лучше всего, если Label может также связывать другие атрибуты со значениями в виртуальной машине.
Спасибо, Джейсон, это сработало! Мне не нужно было реализовывать
INotifyPropertyChanged, потому чтоContentPageнаследуется отBindableObject, который уже реализует его.