我创建了一个模板,该模板适合于允许用户填写表格的系统。我目前遇到的问题是,我创建的模板使用一个下拉框,该框允许用户从从问题模型上的自定义属性提取的列表中选择一个整数。 (我知道这听起来有多恐怖,因此可能很容易通过示例展示)
下面的两个片段显示了下拉问题类型的数据模板。第一个显示了我希望通过itemssource提取问题中的下拉选项并保存它们的愿望。但这是行不通的-它显示了单击该条目后拉入的选项,然后将它们添加到框中。保存页面并重新打开后,先前的选择将恢复为空。
Questions.xaml-从itemssource下拉模板(不起作用)
<DataTemplate x:Key="DropdownTemplate">
<StackLayout IsVisible="{Binding IsVisible}" HeightRequest="{Binding RowHeight}" Padding="{Binding IndentPadding}">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Text}" StyleClass="QuestionText"/>
<Picker SelectedItem="{Binding Answer, Converter={StaticResource DropDownConverter},Mode=TwoWay}" StyleClass="QuestionAnswer" WidthRequest="100" ItemsSource="{Binding DropdownOptions}"></Picker>
</StackLayout>
<BoxView StyleClass="ListBreak"/>
</StackLayout>
</DataTemplate>
Questions.xaml-下拉模板进行硬编码(工作)
<DataTemplate x:Key="DropdownTemplate">
<StackLayout IsVisible="{Binding IsVisible}" HeightRequest="{Binding RowHeight}" Padding="{Binding IndentPadding}">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Text}" StyleClass="QuestionText"/>
<Picker SelectedItem="{Binding Answer, Converter={StaticResource DropDownConverter},Mode=TwoWay}" StyleClass="QuestionAnswer" WidthRequest="100" ItemsSource="{Binding DropdownOptions}">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:Int32}">
<x:Int32>1</x:Int32>
<x:Int32>2</x:Int32>
</x:Array>
</Picker.ItemsSource>
</Picker>
</StackLayout>
<BoxView StyleClass="ListBreak"/>
</StackLayout>
</DataTemplate>
从调试中,我可以看到单击该选项并进行保存可以按预期进行,但是在重新打开包含新保存的条目的页面时,该值正确进入了转换器-已转换-似乎已按预期完成并工作。然后再次触发转换器,并且“值”字段为空,然后将条目设置为空,从而反转先前的选择。 (硬编码版本可以按预期正确访问转换器)
下拉转换器
public class DropDownConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
int final = Int32.Parse(value.ToString());
return final;
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null)
{
string final = value.ToString();
return final;
}
return null;
}
}
问题示例(来自模型)
[QuestionAttribute(dropdownOptions = new List<int> ( 1, 2)]
[Display(Name = "QuestionName")]
public int? Question { get; set; }
QuestionAttribute
[AttributeUsage(AttributeTargets.Property)]
public class QuestionAttribute : Attribute
{
public int[] dropdownOptions { get; set; }
}
抱歉,如果不清楚其中的任何一个,我很乐意回答更多问题,或在必要时提供应用程序的图像。我可以肯定地说,问题在于从特定问题的问题属性获取项目源的过程中。有一个更好的方法吗?它应该放在列表中吗?
非常感谢您的帮助!
您是否想获得如下GIF所示的结果。
我不知道您使用的特定StyleClass
。我删除了所有这些。
我用Mvvm实现了。您可以参考它。
首先,这是布局。
<ContentPage.Resources>
<ResourceDictionary>
<local:DropDownConverter x:Key="DropDownConverter" />
</ResourceDictionary>
</ContentPage.Resources>
<StackLayout>
<!-- Place new controls here -->
<ListView Margin="0,20,0,0" ItemsSource="{Binding myModels}">
<ListView.ItemTemplate>
<DataTemplate >
<ViewCell>
<StackLayout IsVisible="{Binding IsVisible}" HeightRequest="{Binding RowHeight}" Padding="{Binding IndentPadding}">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Text}" />
<Picker ItemsSource="{Binding DropdownOptions}" SelectedItem="{Binding Answer,Converter={StaticResource DropDownConverter}, Mode=TwoWay}" WidthRequest="100" ></Picker>
</StackLayout>
<BoxView />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这里是布局背景代码。
public MainPage()
{
InitializeComponent();
BindingContext = new MyViewModel();
}
这是我的视图模型。
public class MyViewModel
{
public ObservableCollection<MyModel> myModels { get; set; }
public MyViewModel()
{
myModels = new ObservableCollection<MyModel>();
myModels.Add(new MyModel() { Answer=1, DropdownOptions= new int[]{ 1, 2 ,3, 4 }, IndentPadding=3, IsVisible=true, RowHeight=30, Text="test1" });
myModels.Add(new MyModel() { Answer = 2, DropdownOptions = new int[] { 1, 2, 3, 4 }, IndentPadding = 3, IsVisible = true, RowHeight = 30, Text = "test2" });
myModels.Add(new MyModel() { Answer = 1, DropdownOptions = new int[] { 1, 2, 3, 4 }, IndentPadding = 3, IsVisible = true, RowHeight = 30, Text = "test3" });
myModels.Add(new MyModel() { Answer = 3, DropdownOptions = new int[] { 1, 2, 3, 4 }, IndentPadding = 3, IsVisible = true, RowHeight = 30, Text = "test4" });
myModels.Add(new MyModel() { Answer = 2, DropdownOptions = new int[] { 1, 2, 3, 4 }, IndentPadding = 3, IsVisible = true, RowHeight = 30, Text = "test5" });
myModels.Add(new MyModel() { Answer = 4, DropdownOptions = new int[] { 1, 2, 3, 4 }, IndentPadding = 3, IsVisible = true, RowHeight = 30, Text = "test6" });
}
}
这是我的模特。
public class MyModel
{
public bool IsVisible { get; set; }
public int RowHeight { get; set; }
public int IndentPadding { get; set; }
public string Text { get; set; }
public int[] DropdownOptions { get; set; }
public int Answer { get; set; }
}
感谢莱昂提供您上面提供的代码。很抱歉,我对我需要什么的解释很拙劣,我已经从一家外部公司继承了该应用程序,并且有很多事情在试图解决这个问题。我认为我的解释不力,没有任何图像可以说明我的工作,这使您走错了路。下次,我将牢记这一点,并确保记录该应用程序当时在做什么以帮助您。
令人讨厌的是,这似乎是xamarin中的错误导致了我的问题。 This link这是要点。出于某些奇怪的原因,对选择器内部的属性重新排序可以解决此问题。
本质上是,一旦我的代码(其行为与上面发布的代码非常相似)在选择器中选择了值,然后将该值保存到表单中。退出并重新进入该页面后,该页面尝试使用先前保存的选择器值填充选择器值-拥有选择器属性的顺序与它们先前的顺序相同,意味着转换器正常工作(使用convert将值转换为int,转换回以将其返回为字符串),然后重新输入以null为值的convertback,因此将选择器返回为null,这使我的生活很痛苦。
非常感谢您的帮助,这对我的工作有所帮助!