【发布时间】:2017-06-14 13:30:34
【问题描述】:
我是 Xamarin 表单应用程序开发的新手,想尝试一个简单的应用程序,该应用程序将从文本字段中获取字符串并通过数据绑定将其放置在标签中。
- 文本字段距离两侧和垂直中心有 20 px 的边距。
- 标签将位于文本字段下方。
- 在 textField 中输入时,标签将更新 (MVVM)
- UI 设计将来自 XAML。
谢谢。
【问题讨论】:
标签: xaml mvvm data-binding xamarin.forms
我是 Xamarin 表单应用程序开发的新手,想尝试一个简单的应用程序,该应用程序将从文本字段中获取字符串并通过数据绑定将其放置在标签中。
谢谢。
【问题讨论】:
标签: xaml mvvm data-binding xamarin.forms
如果您使用 Xamarin Forms 来实现这一点并使用 DataBinding (MVVM),首先在您的 ViewModel(我们将其称为 MainPageViewModel.cs)中,您需要这样的东西:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SandboxForms.ViewModels
{
public class MainPageViewModel : INotifyPropertyChanged
{
private string _myTextField;
public string MyTextField
{
get { return _myTextField; }
set
{
_myTextField = value;
OnPropertyChanged(nameof(MyTextField));
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var handler = PropertyChanged;
if (handler != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
然后在我们的 ContentPage 中(我们将其称为 MainPage.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"
x:Class="SandboxForms.Pages.MainPage"
xmlns:viewmodels="clr-namespace:SandboxForms.ViewModels;SandboxForms">
<ContentPage.BindingContext>
<viewmodels:MainPageViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Padding="20">
<!-- I am applying EndAndExpand to the entry and
StartAndExpand to the label to center them each other -->
<Entry
HorizontalOptions="FillAndExpand"
VerticalOptions="EndAndExpand"
Placeholder="Write here and see the magic!!!"
Text="{Binding MyTextField}"/>
<Label
HorizontalTextAlignment="End"
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand"
Text="{Binding MyTextField}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
以下是一些结果的屏幕截图: Application starting, Entering text on your Entry 希望这对你有用,我最好的问候!
【讨论】:
有两种数据绑定方法,每种方法都有各自的优点,具体取决于具体情况。第一个是前面提到的 MVVM。这适用于您的 ViewModel 应该知道的字段,例如输入字段中的文本,但情况并非总是如此,因此在选择适合您需要的正确方法之前有一个完整的了解非常重要。
public class MyPageViewModel : INotifyPropertyChanged
{
private string myTextField;
public string MyTextField
{
get { return myTextField; }
set
{
if( !myTextField.Equals( value ) )
{
myTextField = value;
OnPropertyChanged("MyTextField");
}
}
}
}
<?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:Class="SandboxForms.Pages.MainPage"
xmlns:viewmodels="clr-namespace:SandboxForms.ViewModels;SandboxForms">
<ContentPage.BindingContext>
<viewmodels:MainPageViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Padding="20">
<!-- I am applying EndAndExpand to the entry and
StartAndExpand to the label to center them each other -->
<Entry
HorizontalOptions="FillAndExpand"
VerticalOptions="EndAndExpand"
Placeholder="Write here and see the magic!!!"
Text="{Binding MyTextField}"/>
<Label
HorizontalTextAlignment="End"
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand"
Text="{Binding MyTextField}"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
这通常是大多数开发人员首选的方法,而不是直接在 UI 后面的代码中混合业务逻辑。
如果您不熟悉,可以查看许多帮助程序和框架。以下是一些比较流行的。
有时直接绑定到 ViewModel 的属性实际上会违反 MVVM 模式,而有时我们可能希望在 View 中显示某些内容而不需要更新 ViewModel 中的支持字段。例如,我们可以查看Xamarin's guide to data binding。
<?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:Class="XamlSamples.SliderBindingsPage"
Title="Slider Bindings Page">
<StackLayout>
<Label Text="ROTATION"
BindingContext="{x:Reference Name=slider}"
Rotation="{Binding Path=Value}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
<Slider x:Name="slider"
Maximum="360"
VerticalOptions="CenterAndExpand" />
<Label BindingContext="{x:Reference slider}"
Text="{Binding Value,
StringFormat='The angle is {0:F0} degrees'}"
FontAttributes="Bold"
FontSize="Large"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
我应该注意,我建议使用这种方法的最常见的时间之一是在 ListView 中使用上下文操作,因为我们的 ViewModel 可能包含我们想要在单个单元格上执行的命令,但是我们在其中的单元格正在执行的上下文动作实际上是从我们的IEnumerable<T> 绑定到对象,而不是我们的 ViewModel。在这种特殊情况下,我们将执行以下操作:
<?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="someListPage"
x:Class="MyApp.Views.SomeListPage">
<ListView ItemsSource="{Binding Gear}"
CachingStrategy="RecycleElement"
IsRefreshing="{Binding IsRefreshing}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Description}" Detail="{Binding Detail}">
<TextCell.ContextActions>
<MenuItem Text="Remove"
Command="{Binding BindingContext.RemoveItemCommand,Source={x:Reference someListPage}}"
CommandParameter="{Binding .}"
IsDestructive="True" />
</TextCell.ContextActions>
</TextCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
您会注意到,要使其正常工作,我们首先为页面本身指定一个名称,然后我们可以引用该名称来绑定ContextAction Command 属性。这只会改变我们在哪里寻找这个单一的属性。然后,我们继续使用 CommandParameter 属性的普通绑定上下文,并通过 {Binding .} 传入单元格绑定到的实际对象
希望这有助于您更好地了解与 Xaml 绑定的选项。快乐编码!
【讨论】: