在UWP中,当在listview datatemplate中使用组合框时,selectedItem将丢失

时间:2018-03-22 11:51:40

标签: listview combobox uwp itemtemplate

有几个类似的问题,但我找不到任何看起来与我所经历的完全相同的东西。

ComboBox DataTemplate内有ListView ComboBoxItemsSourceSelectedItem以及null具有正确的绑定。我使用的模式与我在整个应用程序中使用的模式相同,没有任何问题。

无论出于何种原因,所选项目都会在整个过程中被淘汰。我在所选项目中放置了断点,我可以看到它在列表构建期间正确设置。然后,在渲染控件时,所选项目再次设置为null(至少是它出现的方式)。当我查看调用堆栈时,它被设置为[External Code],堆栈只显示<ListView ItemsSource="{x:Bind Vm.ListVms, Mode=OneWay}" SelectedItem="{x:Bind Vm.SelectedListVm, Mode=TwoWay, Converter={StaticResource GenericConverter}}"> <ListView.ItemTemplate> <DataTemplate x:DataType="ListItemVm"> <StackPanel Orientation="Horizontal"> <ComboBox ItemsSource="{x:Bind ComboBoxTypes, Mode=OneWay}" SelectedItem="{x:Bind SelectedComboBoxType, Mode=TwoWay, Converter={StaticResource GenericConverter}}" DisplayMemberPath="Name"/> </StackPanel> </DataTemplate> </ListView.ItemTemplate> 上的行I&#39; m。

作为参考,这是当前代码的样子:

ComboBoxTypes

ObservableCollectionSelectedComboBoxType。 通过引用RaceTypes中的行来设置ListView

同样,正如我上面提到的,这种模式似乎适用于应用程序中的其他任何位置,但不在 vm.ListVms.Clear(); foreach (var unit in source.ListItems) { var listVm = new ListVm(); listVm.ComboBoxTypes.Add(); listVm.ComboBoxTypes.Add(); listVm.ComboBoxTypes.Add(); listVm.ComboBoxTypes.Add(); listVm.SelectedComboBoxType = listVm.ComboBoxTypes.FirstOrDefault(r => r.Id == (int) unit.ComboBoxType); vm.ListVms.Add(listVm); } 内。

以下是我用来填充列表项和组合框的代码示例。它不是实际代码,因为我无法提供实际代码。虽然它足够接近,但它说明了正在采取的步骤。

src/test/java

2 个答案:

答案 0 :(得分:0)

当您反转在代码隐藏中选择项目的顺序时,通常会发生这种情况。请考虑以下两个选项:

选项1

SelectedComboBoxType = items[0];
ComboBoxTypes = items;

选项2

ComboBoxTypes = items;
SelectedComboBoxType = items[0];

选项1 中,您首先设置所选项目,该项目会导致更改通知,该更改通知由控件立即处理。但是,该控件尚未绑定到items,因此不会将SelectedItem设置为您的选择,但相反会导致使用之前选择的值更新回SelectedComboBoxType

基本上这意味着您只能在之后选择,您想要选择的值已经绑定到控件。 选项2 应该可以解决您的问题。

答案 1 :(得分:0)

我从微软开发者网络收到了一些可行的答案,所以我想我会在这里与任何遇到同样问题的人分享。

选项1 如果值为null,则对setter进行测试以绕过更新后备字段。

对我来说这是一个黑客,但它完美无缺。

public ComboboxItemVm SelectedComboBoxType
{
    get { return selectedType; }
    set
    {
        if (value == null)
        {
            Debug.WriteLine("null!");
            return;
        }
        if (value != selectedType)
        {
            selectedType = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("SelectedComboBoxType"));
        }
    }
}

选项2 从x:Bind to Binding更改SelectedItem上的绑定。

<ComboBox 
    ItemsSource="{x:Bind ComboBoxTypes, Mode=OneWay}"
    SelectedItem="{Binding SelectedComboBoxType, Mode=TwoWay, Converter={StaticResource GenericConverter}}"
    DisplayMemberPath="Name"/>

令人失望的是,解决方案是使用较旧的编码风格,但它也解决了问题,而无需在代码中添加额外的null-test-bypass选项。

Here is a link to the original answer provided to me