我已经读过编辑器控件没有占位符,所以我一直试图做一个没有成功的解决方法。我知道Entry控件有一个占位符,但我需要多行字段,因为我打算将它用作用户可以编写注释的字段,而不仅仅是一行。
这是我的方法:
我试图将编辑器和标签放入网格控件中,标签位于编辑器的顶部。编辑器的InputTransparent
标志设置为true
。然后我根据IsVisible
是否包含文本来切换标签的Editor
属性。但问题是我使用的是MVVM模式,因此我不知道如何控制TextChanged
中的ViewModel
事件。我也尝试过编码,但是找不到标签的名称。
这是我的XAML代码 - 只发布了相关代码:
<Grid Grid.Row="1">
<Editor Text="{Binding UserComment, Mode=TwoWay}" TextChanged="EditorTextChanged" HorizontalOptions="FillAndExpand"/>
<Label x:Name="PlaceholderLabel" Text="Write a comment" InputTransparent="True" HorizontalOptions="StartAndExpand"/>
</Grid>
目前,在代码隐藏中,我只有EditorTextChanged
事件,它可以正常运行,但无法找到PlaceholderLabel
。我把整个View绑定到了我的ViewModel,是这个原因?如果你必须遵循MVVM模式,怎么会接近呢?
值得一提的是,我尝试了this方法。但是,它并没有按预期工作。只有当我点击编辑器然后取消选中它时,才会显示占位符。它应该像Facebook一样出现在开头。
修改
这是整个XAML代码:
<ContentPage.Resources>
<ResourceDictionary>
<local:TeamAlignmentConverter x:Key="teamConverter"/>
<local:ImageAlignmentConverter x:Key="imageConverter"/>
<local:BooleanReverser x:Key="booleanReverser"/>
</ResourceDictionary>
</ContentPage.Resources>
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" Spacing="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="180"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.BindingContext>
<viewModel:MatchPageVM/>
</Grid.BindingContext>
<Grid BackgroundColor="White" RowSpacing="0" Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*" />
<RowDefinition Height="2*" />
<RowDefinition Height="0.8*" />
</Grid.RowDefinitions>
<Label Text="{Binding Teams}" FontSize="26" HorizontalOptions="CenterAndExpand" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" VerticalOptions="CenterAndExpand" Grid.Row="0"/>
<Image Source="notificationsbell.png" Margin="25,10,0,0" HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand" Grid.Row="1"/>
<Label Text="{Binding Score}" FontSize="80" HorizontalOptions="CenterAndExpand" HorizontalTextAlignment="Center" VerticalOptions="CenterAndExpand" VerticalTextAlignment="Center" Grid.Row="1"/>
<Label Text="Live" FontSize="24" HorizontalOptions="CenterAndExpand" HorizontalTextAlignment="Center" VerticalOptions="CenterAndExpand" VerticalTextAlignment="Center" Grid.Row="2"/>
</Grid>
</Grid>
<Grid RowSpacing="0" VerticalOptions="FillAndExpand">
<Grid.BindingContext>
<viewModel:MatchPageVM/>
</Grid.BindingContext>
<cv:CarouselView ItemsSource="{Binding CollectionList}">
<cv:CarouselView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<flv:FlowListView x:Name="flowListView" FlowColumnCount="1" Grid.Row="0"
SeparatorVisibility="None" HasUnevenRows="True" IsVisible="{Binding ListSwitch}"
FlowItemsSource="{Binding CollectionList}" BackgroundColor="White" >
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Grid ColumnSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.005*"/>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Text="{Binding PlayerName}" Grid.Column="{Binding Team}" VerticalOptions="Center"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="{Binding Team, Converter={StaticResource teamConverter}}"/>
<Image Source="{Binding ImageURL}" HorizontalOptions="Center" Grid.Column="{Binding Team, Converter={StaticResource imageConverter}}" Aspect="AspectFill" VerticalOptions="Center"/>
<BoxView BackgroundColor="Black" Grid.Column="2" HeightRequest="20" VerticalOptions="Center"/>
</Grid>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<flv:FlowListView x:Name="flowListView2" FlowColumnCount="1" BackgroundColor="White"
HasUnevenRows="True" HeightRequest="180" IsVisible="{Binding ListSwitch, Converter={StaticResource booleanReverser}}" Grid.Row="0"
FlowItemsSource="{Binding CollectionList}" SeparatorVisibility="Default" SeparatorColor="Black">
<flv:FlowListView.FlowColumnTemplate>
<DataTemplate>
<Grid RowSpacing="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageURL}" HorizontalOptions="Start"
Grid.Row="0" Grid.Column="0" Aspect="AspectFit" Margin="0,10,0,0" VerticalOptions="Start"/>
<Label Text="{Binding UserName}" Grid.Row="0" Grid.Column="1" VerticalOptions="Start"
HorizontalOptions="Start" FontSize="Medium" FontAttributes="Bold" HorizontalTextAlignment="Start" Margin="0,10,0,5" />
<Label Text="{Binding UserComment}" Grid.Row="1" Grid.Column="0" VerticalOptions="Start"
HorizontalOptions="StartAndExpand" FontSize="Medium" HorizontalTextAlignment="Start" Grid.ColumnSpan="2" Margin="0,0,0,10" />
</Grid>
</DataTemplate>
</flv:FlowListView.FlowColumnTemplate>
</flv:FlowListView>
<Grid Grid.Row="1" IsVisible="{Binding ListSwitch, Converter={StaticResource booleanReverser}}">
<Editor Text="{Binding UserComment, Mode=TwoWay}"
HorizontalOptions="FillAndExpand">
<Editor.BindingContext>
<viewModel:MatchPageVM/>
</Editor.BindingContext>
</Editor>
<Label Text="Skriv en kommentar"
HorizontalOptions="StartAndExpand" IsVisible="{Binding LabelIsVisible}" InputTransparent="True">
<Label.BindingContext>
<viewModel:MatchPageVM/>
</Label.BindingContext>
</Label>
</Grid>
</Grid>
</Grid>
</DataTemplate>
</cv:CarouselView.ItemTemplate>
</cv:CarouselView>
</Grid>
</StackLayout>
</ContentPage.Content>
答案 0 :(得分:1)
您正在寻找的是自定义渲染器,您可以看到,因为Xamarin.Forms只是本机元素的另一个级别,您可以使用CustomRenderer“访问”本机元素:
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/
您可以创建基本自定义编辑器:
using Xamarin.Forms;
namespace EditorWithPlaceholder
{
public class PlaceholderEditor : Editor
{
public static BindableProperty PlaceholderProperty
= BindableProperty.Create(nameof(Placeholder), typeof(string), typeof(PlaceholderEditor));
public static BindableProperty PlaceholderColorProperty
= BindableProperty.Create(nameof(PlaceholderColor), typeof(Color), typeof(PlaceholderEditor), Color.Gray);
public string Placeholder
{
get { return (string) GetValue(PlaceholderProperty); }
set { SetValue(PlaceholderProperty, value); }
}
public Color PlaceholderColor
{
get { return (Color) GetValue(PlaceholderColorProperty); }
set { SetValue(PlaceholderColorProperty, value); }
}
}
}
每个平台上的渲染器:
机器人:
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PlaceholderEditor), typeof(PlaceholderEditorRenderer))]
namespace EditorWithPlaceholder.Droid.Renderers
{
public class PlacehoderEditorRenderer : EditorRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
var element = (PlaceholderEditor) Element;
Control.Hint = element.Placeholder;
Control.SetHintTextColor(element.PlaceholderColor.ToAndroid());
}
}
}
的iOS:
using System;
using Cirrious.FluentLayouts.Touch;
using Foundation;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(PlaceholderEditor), typeof(PlaceholderEditorRenderer))]
namespace EditorWithPlaceholder.iOS.Renderers
{
public class PlaceholderEditorRenderer : EditorRenderer
{
private UILabel _placeholderLabel;
protected override void OnElementChanged(ElementChangedEventArgs<Editor> e)
{
base.OnElementChanged(e);
if (Element == null)
return;
CreatePlaceholderLabel((PlaceholderEditor) Element, Control);
Control.Ended += OnEnded;
Control.TextChanged += OnChanged;
}
private void CreatePlaceholderLabel(PlaceholderEditor element, UITextView parent)
{
_placeholderLabel = new UILabel
{
Text = element.Placeholder,
TextColor = element.PlaceholderColor.ToUIColor(),
BackgroundColor = UIColor.Clear,
Font = UIFont.FromName(element.FontFamily, (nfloat)element.FontSize)
};
_placeholderLabel.SizeToFit();
parent.AddSubview(_placeholderLabel);
parent.SubviewsDoNotTranslateAutoresizingMaskIntoConstraints();
parent.AddConstraints(
_placeholderLabel.AtLeftOf(parent, 7),
_placeholderLabel.WithSameCenterY(parent)
);
parent.LayoutIfNeeded();
_placeholderLabel.Hidden = parent.HasText;
}
private void OnEnded(object sender, EventArgs args)
{
if (!((UITextView) sender).HasText && _placeholderLabel != null)
_placeholderLabel.Hidden = false;
}
private void OnChanged(object sender, EventArgs args)
{
if (_placeholderLabel != null)
_placeholderLabel.Hidden = ((UITextView) sender).HasText;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
Control.Ended -= OnEnded;
Control.Changed -= OnChanged;
_placeholderLabel?.Dispose();
_placeholderLabel = null;
}
base.Dispose(disposing);
}
}
}
我希望这些信息有所帮助。
供参考: https://solidbrain.com/2017/07/10/placeholder-text-in-xamarin-forms-editor/
答案 1 :(得分:1)
以下是您自己提到的方法:
<AbsoluteLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Editor
Text="{Binding Address, Mode=TwoWay}"
HorizontalOptions="FillAndExpand"
AbsoluteLayout.LayoutFlags="PositionProportional, WidthProportional"
AbsoluteLayout.LayoutBounds="0,0,1.01,100">
</Editor>
<Label Text="MyPlaceHolder" IsVisible="{Binding IsAddrerssPlaceHolderVisible}" HorizontalTextAlignment="Center"
AbsoluteLayout.LayoutBounds="0.5,0.5, 1, 0.5" VerticalTextAlignment="Center"
AbsoluteLayout.LayoutFlags="All" InputTransparent="True"/>
</AbsoluteLayout>
这是Viewmodel部分:
public bool IsAddrerssPlaceHolderVisible
{
get => _isAddrerssPlaceHolderVisible;
set
{
_isAddrerssPlaceHolderVisible= value;
RaisePropertyChanged();
}
}
public string Address
{
get => _address;
set
{
_address = value;
if (value.Length > 0)
{
IsAddrerssPlaceHolderVisible= false;
}
else
{
IsAddrerssPlaceHolderVisible= true;
}
RaisePropertyChanged();
}
}
它甚至不需要我之前提到过的任何其他错误!它的工作原理很简单:D