【发布时间】:2021-09-25 16:06:38
【问题描述】:
Xamarin 表单的新手,在过去一天半的时间里试图弄清楚为什么我的某些绑定有效而其他绑定无效。它们的构造方式相同,但行为不同。大多数元素都绑定到我创建的可观察对象集合,这些对象是从我的 API 中的 ENUMS 中提取的。 XAML 选择器正确加载了我的集合——当我的应用程序正在运行并且我单击选择器时,我可以很好地查看列表。问题是 SelectedItem 的绑定。标签类型选择器正确显示所选项目,模拟类型选择器不显示我选择的项目 - 它是空白的(当我单击选择器时,集合仍然显示,只是所选项目是空白的)。这两个属性在我创建的服务中以相同的方式同时设置,以实现与模型中的属性交互的方法。然后,视图模型创建该服务的实例以访问属性。需要注意的一件奇怪的事情是,当热重载正在运行并且我删除然后重新添加此行时: SelectedItem="{Binding MyItemSimulationType}" 它可以工作!但是一旦我关闭程序并重新运行应用程序,所选项目再次为空白:/
输出窗口显示以下内容:
[0:] Binding: '' cannot be converted to type 'TagType'
[0:] Binding: '' cannot be converted to type 'SimulationType'
奇怪的部分是 TagType 的绑定有效而 SimulationType 无效。这是 XAML:
<RefreshView x:DataType="local:ReadWriteViewModel" Command="{Binding LoadReadWriteValuesCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<ScrollView>
<StackLayout Padding="10">
<!--Item Properties-->
<Frame>
<StackLayout>
<Label Text="Item" FontSize="Subtitle" TextColor="Black" VerticalTextAlignment="Center" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!--Tag Type-->
<Label Grid.Row="0" Grid.Column="0" Text="Tag Type" VerticalTextAlignment="Center" HorizontalTextAlignment="End"/>
<Picker Grid.Row="0" Grid.Column="1" FontSize="Small" ItemsSource="{Binding MyItemHWTagTypes}" SelectedItem="{Binding MyItemHWTagType}" >
<Picker.Items></Picker.Items>
</Picker>
<!--Simulation Type-->
<Label Grid.Row="1" Grid.Column="0" Text="Simulation Type" VerticalTextAlignment="Center" HorizontalTextAlignment="End" />
<Picker Grid.Row="1" Grid.Column="1" FontSize="Small" ItemsSource="{Binding MyItemSimulationTypes}" SelectedItem="{Binding MyItemSimulationType}" HorizontalOptions="FillAndExpand">
<Picker.Items></Picker.Items>
</Picker>
</Grid>
</StackLayout>
</Frame>
</StackLayout>
</ScrollView>
</RefreshView>
视图模型:
private ObservableCollection<TagType> _itemHWTagTypes;
private TagType _itemHWTagType;
private ObservableCollection<SimulationType> _itemSimulationTypes;
private SimulationType _itemSimulationType;
public ObservableCollection<TagType> MyItemHWTagTypes
{
get => _itemHWTagTypes;
set => SetProperty(ref _itemHWTagTypes, value);
}
public TagType MyItemHWTagType
{
get => _itemHWTagType;
set => SetProperty(ref _itemHWTagType, value);
}
public ObservableCollection<SimulationType> MyItemSimulationTypes
{
get => _itemSimulationTypes;
set => SetProperty(ref _itemSimulationTypes, value);
}
public SimulationType MyItemSimulationType
{
get => _itemSimulationType;
set => SetProperty(ref _itemSimulationType, value);
}
public Command LoadReadWriteValuesCommand { get; }
public ReadWriteViewModel()
{
//Load Model
LoadReadWriteValuesCommand = new Command(async () => await ExecuteLoadReadWriteValuesCommand());
}
async Task ExecuteLoadReadWriteValuesCommand()
{
IsBusy = true;
try
{
var asc = await ASCService.GetASCObjectAsync();
// ----- Set Item properties to default values in model
MyItemHWTagTypes = asc.ModelItemHWTagTypes;
MyItemHWTagType = asc.ModelItemHWTagType;
MyItemSimulationTypes = asc.ModelItemSimulationTypes;
MyItemSimulationType = asc.ModelItemSimulationType;
}
catch (TaskCanceledException tcex)
{
Debug.WriteLine(tcex);
}
finally
{
IsBusy = false;
}
}
如果需要更多代码,请告诉我,我尝试在此处的示例代码中保持简化,并删除了与我的问题无关的额外代码。我在 ExecuteLoadReadWriteValuesCommand() 中的所有属性都设置正确,所以我确信这不是问题。 我的输出窗口中也收到了很多其他垃圾邮件,我认为这些消息不相关,但也许?这些是看起来可能有问题的:
[TabLayout] MODE_SCROLLABLE + GRAVITY_FILL is not supported, GRAVITY_START will be used instead
[Choreographer] Skipped 38 frames! The application may be doing too much work on its main thread.
[OpenGLRenderer] Davey! duration=1656ms; Flags=0, IntendedVsync=1769860264400, Vsync=1770843597694, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=1770846662700, AnimationStart=1770846714100, PerformTraversalsStart=1770847196400, DrawStart=1771495643200, SyncQueued=1771503136700, SyncStart=1771503918600, IssueDrawCommandsStart=1771504436800, SwapBuffers=1771515968100, FrameCompleted=1771517457000, DequeueBufferDuration=303000, QueueBufferDuration=902000,
【问题讨论】:
-
要绑定
SelectedItem的项目需要是ItemsSource集合中包含的元素 -
@Jason 这是...
-
它必须是同一个实例,而不是同一个对象的两个副本。尝试设置 MyItemSimulationType = MyItemSimulationTypes[0] 来检查
-
首先按照杰森的建议去做,排除一些可能性。然后 1) 您已验证
asc.ModelItemSimulationType不为空? 2) 何时/如何调用LoadReadWriteValuesCommand?在构建视图时?还是 OnAppearing?还是以后? 3) 作为测试,在 VM 构造函数中硬编码一个列表,并注释掉对服务的延迟调用——它有效吗? 4)切换分配顺序,所以MyItemSimulationType设置在MyItemHWTagType之前 - 症状会改变吗? -
5)
ExecuteLoadReadWriteValuesCommand中的断点,位于设置 Item 属性的第一行。检查您所在的线程 - 它应该是 UI 线程。
标签: c# xaml xamarin.forms mvvm data-binding