目前我正试图以对话形式将xamarin表单作为用户控件复制到android日期选择器,以用于练习目的,因为我真的讨厌iPhone日期选择器......不管怎样,现在一切正常好的,我可以选择一天,在几个月之间切换,选择一年等等。
但是现在只能解决我自己无法解决的一个小问题。 日期的起始ui包含年份和所选日期,如
2017年 - 2月22日星期三
如果用户点击年份,则会隐藏日期选择器并显示具有可用年份的listView。这也很好,我的问题是我想滚动到选定的年份,如果在提供的年份。但这只适用于我今年两次点击的情况。
因此,让我们说用户点击" 2017",现在他会看到列表视图并且不滚动并显示最上面的第一个项目。现在他轻拍了#34; 2017"再次,最后listView滚动到该位置,以便带有" 2017"显示在用户的中心。 也许下图更好地解释了它(开始 - > 2017年首次点击 - > 2017年第二次点击)
我做错了什么,有什么我看不到的吗?如果列表视图本身不可见,高度是否可能导致该行为?
注意:我已尝试使用scrollTo
的设置或在创建实际视图时(即在构造函数或SelectedDate
中)调用OnBindingContextChanged
。
注意2:第一次if(sender == YearLabel)
检查为真,selection
不为空但与第二次相同的值
XAML的重要部分
<StackLayout BackgroundColor="{DynamicResource AccentColor}" Spacing="5" Padding="15" Grid.Row="0">
<Label Text="{Binding SelectedDate, StringFormat='{0:yyyy}', Source={x:Reference this}}" FontSize="Medium" TextColor="LightGray" x:Name="YearLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnDateLabelTapped"/>
</Label.GestureRecognizers>
</Label>
<Label Text="{Binding SelectedDate, StringFormat='{0:ddd, d. MMMM}', Source={x:Reference this}" FontSize="Large" TextColor="White" x:Name="DayLabel">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="OnDateLabelTapped"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
<StackLayout Grid.Row="1">
<StackLayout x:Name="YearPicker" IsVisible="False" HorizontalOptions="FillAndExpand" Spacing="0">
<ListView ItemSelected="OnYearSelected" x:Name="YearList" ItemTemplate="{StaticResource dateDataTemplateSelector}" SeparatorVisibility="None" />
<BoxView HeightRequest="1" HorizontalOptions="FillAndExpand" Color="#efefef" />
</StackLayout>
... other stuff
中的代码
public ObservableCollection<YearViewModel> Years { get; set; }
public DateTime SelectedDate
{
get { return (DateTime)GetValue(SelectedDateProperty); }
set { SetValue(SelectedDateProperty, value); }
}
private void OnDateLabelTapped(object sender, EventArgs args)
{
if(sender == YearLabel)
{
YearLabel.TextColor = Color.White;
DayLabel.TextColor = Color.LightGray;
YearPicker.IsVisible = true;
DayPicker.IsVisible = false;
var selection = Years.FirstOrDefault(y => y.Date.Year == SelectedDate.Year);
YearList.ScrollTo(selection, ScrollToPosition.Center, true);
}
else if(sender == DayLabel)
{
DayLabel.TextColor = Color.White;
YearLabel.TextColor = Color.LightGray;
DayPicker.IsVisible = true;
YearPicker.IsVisible = false;
}
}
如果您认为更多代码可能会有所帮助,请告诉我们!
答案 0 :(得分:1)
所以,因为我一次又一次地调试这个,我猜是因为在设置YearPicker.IsVisible = true;
之后直接缺少listView的高度是正确的。我对自己有点恼火,以前我没有看到过这个,但是没问题。
我目前的解决方案是
private void OnDateLabelTapped(object sender, EventArgs args)
{
if(sender == YearLabel)
{
YearLabel.TextColor = Color.White;
DayLabel.TextColor = Color.LightGray;
YearPicker.IsVisible = true;
DayPicker.IsVisible = false;
Device.StartTimer(TimeSpan.FromMilliseconds(20), () =>
{
var selection = Years.FirstOrDefault(y => y.Date.Year == SelectedDate.Year);
YearList.ScrollTo(selection, ScrollToPosition.Center, true);
return false;
});
}
else if(sender == DayLabel)
{
DayLabel.TextColor = Color.White;
YearLabel.TextColor = Color.LightGray;
DayPicker.IsVisible = true;
YearPicker.IsVisible = false;
}
}
所以基本上我只需要等待几毫秒来确保listview计算出它的高度并显示每个条目。
由于这种感觉很多就像黑客一样,我会感谢任何其他/更好的解决方案。
我已经尝试过侦听listView的sizeChanged
事件但没有任何结果
YearList.SizeChanged += (s, e) =>
{
var selection = Years.FirstOrDefault(y => y.Date.Year == SelectedDate.Year);
YearList.ScrollTo(selection, ScrollToPosition.Center, true);
};