更新:提醒一下,如果有人可以在不使用手势的情况下向我展示如何实施此功能>
我使用ViewCell和手势识别器打开一个带有以下代码的选择器。 ViewCell左侧有一个标签,右侧有一个标签区域,最初在应用程序启动时填充,稍后在单击ViewCell时填充选择器。
XAML
<ViewCell x:Name="ati" Tapped="OpenPickerCommand">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Grid.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding OpenPickerCommand}"
CommandParameter="{x:Reference atiPicker}" NumberOfTapsRequired="1" />
</Grid.GestureRecognizers>
<local:LabelBodyRendererClass Text="Answer Time Interval" HorizontalOptions="StartAndExpand" />
<Picker x:Name="atiPicker" IsVisible="false" HorizontalOptions="End" SelectedIndexChanged="atiPickerSelectedIndexChanged" ItemsSource="{Binding Times}"></Picker>
<local:LabelBodyRendererClass x:Name="atiLabel" HorizontalOptions="End"/>
</Grid>
</ViewCell>
<ViewCell x:Name="pti" Tapped="OpenPickerCommand">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<Grid.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding OpenPickerCommand}"
CommandParameter="{x:Reference ptiPicker}" NumberOfTapsRequired="1" />
</Grid.GestureRecognizers>
<local:LabelBodyRendererClass Text="Phrase Time Interval" HorizontalOptions="StartAndExpand" />
<Picker x:Name="ptiPicker" IsVisible="false" HorizontalOptions="End" SelectedIndexChanged="ptiPickerSelectedIndexChanged" ItemsSource="{Binding Times}"></Picker>
<local:LabelBodyRendererClass x:Name="ptiLabel" HorizontalOptions="End"/>
</Grid>
</ViewCell>
C#这适用于使用CommandParameter的不同选择器(ati,bti,pti等)
public SettingsPage()
{
InitializeComponent();
BindingContext = new CommandViewModel();
}
void atiPickerSelectedIndexChanged(object sender, EventArgs e)
{
var picker = (Picker)sender;
int selectedIndex = picker.SelectedIndex;
if (selectedIndex != -1)
{
App.DB.UpdateIntSetting(Settings.Ati, selectedIndex);
atiLabel.Text = AS.ati.Text();
}
}
void ptiPickerSelectedIndexChanged(object sender, EventArgs e)
{
var picker = (Picker)sender;
int selectedIndex = picker.SelectedIndex;
if (selectedIndex != -1)
{
App.DB.UpdateIntSetting(Settings.Pti, selectedIndex);
ptiLabel.Text = AS.pti.Text();
}
}
public class CommandViewModel: ObservableProperty
{
public ICommand openPickerCommand;
public CommandViewModel()
{
openPickerCommand = new Command<Picker>(PickerFocus);
//openPickerCommand = new Command(tapped);
}
public ICommand OpenPickerCommand
{
get { return openPickerCommand; }
}
void PickerFocus(Picker param)
{
param.Focus();
}
}
我想删除TapGestureRecognizers的使用,但我仍然希望保留功能和布局。
有人向我建议,如果我像这样使用ViewCell的Tapped事件会更好:
Tapped="OnTapped"
有人可以详细解释我如何用C#连接它。我是否最好在CommandViewModel以及C#支持代码中编写代码。视图模型还有一个方法可以使用参数,因此它可以用来打开不同的选择器吗?
我非常感谢能够做到这一点的一个例子。请注意,如果有一种方法可以通过.cs支持代码进行编码,我并不特别需要使用CommandViewModel。
答案 0 :(得分:2)
(抱歉英语不好)
尽管不是最佳实践,但我猜你可以做这样的事情,解雇视图模型:
<强> XAML:强>
<ViewCell x:Name="ati" Tapped="OpenPickerCommand">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<local:LabelBodyRendererClass Text="Answer Time Interval" HorizontalOptions="StartAndExpand" />
<Picker x:Name="atiPicker"
IsVisible="false"
HorizontalOptions="End"
SelectedIndexChanged="atiPickerSelectedIndexChanged"
ItemsSource="{Binding Times}">
</Picker>
<local:LabelBodyRendererClass x:Name="atiLabel" HorizontalOptions="End"/>
</Grid>
</ViewCell>
<ViewCell x:Name="pti" Tapped="OpenPickerCommand">
<Grid VerticalOptions="CenterAndExpand" Padding="20, 0">
<local:LabelBodyRendererClass Text="Phrase Time Interval" HorizontalOptions="StartAndExpand" />
<Picker x:Name="ptiPicker" IsVisible="false" HorizontalOptions="End" SelectedIndexChanged="ptiPickerSelectedIndexChanged" ItemsSource="{Binding Times}"></Picker>
<local:LabelBodyRendererClass x:Name="ptiLabel" HorizontalOptions="End"/>
</Grid>
</ViewCell>
<强> C#:强>
private void OpenPickerCommand(object sender, System.EventArgs e)
{
if (sender != null)
{
Picker pkr = sender == ati ? atiPicker : ptiPicker;
pkr.Focus();
}
}
回答你的问题&#34;视图模型是否有一种方法可以参与?&#34;,这正是你使用&#39; OpenPickerCommand&#39;方法。问题是,使用ViewCell的公共活动&#39; Tapped&#39;,您无法为委托处理程序设置参数。
请告诉我它是否适合您,或者您是否需要更多信息。
我希望它有所帮助。
答案 1 :(得分:1)
所以有两个不同的问题:显示/隐藏选择器,这可以直接在XAML中实现,或者借助一些代码隐藏;以及必须使用viewmodel中的Command管理的选择器项目选择。
希望这会对你有所帮助
答案 2 :(得分:1)
您可以使用附加属性解决此问题。只需为ViewCell定义一个“ 行为”类即可添加Command / Parameter属性。
public static class TappedCommandViewCell
{
private const string TappedCommand = "TappedCommand";
private const string TappedCommandParameter = "TappedCommandParameter";
public static readonly BindableProperty TappedCommandProperty =
BindableProperty.CreateAttached(
TappedCommand,
typeof(ICommand),
typeof(TappedCommandViewCell),
default(ICommand),
BindingMode.OneWay,
null,
PropertyChanged);
public static readonly BindableProperty TappedCommandParameterProperty =
BindableProperty.CreateAttached(
TappedCommandParameter,
typeof(object),
typeof(TappedCommandViewCell),
default(object),
BindingMode.OneWay,
null);
private static void PropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
if (bindable is ViewCell cell)
{
cell.Tapped -= ViewCellOnTapped;
cell.Tapped += ViewCellOnTapped;
}
}
private static void ViewCellOnTapped(object sender, EventArgs e)
{
if (sender is ViewCell cell && cell.IsEnabled)
{
var command = GetTappedCommand(cell);
var parameter = GetTappedCommandParameter(cell);
if (command != null && command.CanExecute(parameter))
{
command.Execute(parameter);
}
}
}
public static ICommand GetTappedCommand(BindableObject bindableObject) =>
(ICommand)bindableObject.GetValue(TappedCommandProperty);
public static void SetTappedCommand(BindableObject bindableObject, object value) =>
bindableObject.SetValue(TappedCommandProperty, value);
public static object GetTappedCommandParameter(BindableObject bindableObject) =>
bindableObject.GetValue(TappedCommandParameterProperty);
public static void SetTappedCommandParameter(BindableObject bindableObject, object value) =>
bindableObject.SetValue(TappedCommandParameterProperty, value);
}
之后,请在XAML中引用您的行为名称空间,并使用完全限定的名称指定属性值:
<ViewCell StyleId="disclosure-indicator"
behaviors:TappedCommandViewCell.TappedCommand="{Binding BrowseCommand}"
behaviors:TappedCommandViewCell.TappedCommandParameter="https://www.google.com">
<StackLayout Orientation="Horizontal">
<Label Text="Recipient"
VerticalOptions="Center"
Margin="20,0"/>
<Label Text="{Binding LedgerRecord.Recipient}"
HorizontalOptions="EndAndExpand"
VerticalOptions="Center"
Margin="0,0,20,0"/>
</Label>
</StackLayout>
</ViewCell>
以上内容使您可以使用MVVM,而无需使用Tap Gesture Recognizer。