收集重新填充后WPF Combobox绑定中断

时间:2018-04-19 08:42:40

标签: wpf entity-framework data-binding prism-6

我有以下情况。 我有一个ListView设置如下:

<ListView Margin="3,3,3,3" ItemsSource="{Binding Toner}" SelectedValue="{Binding CurrentToner}" IsSynchronizedWithCurrentItem="True">
        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="BorderBrush" Value="LightGray" />
                <Setter Property="BorderThickness" Value="0,0,0,1" />
            </Style>
        </ListView.ItemContainerStyle>

        <ListView.ItemTemplate>
            <DataTemplate>
                <Grid>

                    <Grid.RowDefinitions>
                        <RowDefinition></RowDefinition>
                        <RowDefinition></RowDefinition>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="50"></ColumnDefinition>
                        <ColumnDefinition Width="Auto"></ColumnDefinition>

                    </Grid.ColumnDefinitions>
                    <Label Grid.Row="0" Grid.Column="0" Content="{Binding Id}" FontWeight="Bold"></Label>
                    <Label Grid.Row="0" Grid.Column="1" Content="{Binding Name}" FontWeight="Bold"></Label>
                    <Label Grid.Row="1" Grid.Column="0" Content="{Binding Ratio}">
                    </Label>
                    <Label Grid.Row="1" Grid.Column="1" Content="{Binding TonerType.Name}"  ></Label>

                </Grid>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

我在相应的ViewModel中设置了Property CurrentToner:

private Toner currentToner = new Toner();
public Toner CurrentToner
    {
        get => currentToner;
        set
        {
            SetProperty(ref currentToner, value);
            updateTonerCommand.RaiseCanExecuteChanged();
            deleteTonerCommand.RaiseCanExecuteChanged();
            increaseAmountCommand.RaiseCanExecuteChanged();
            RaisePropertyChanged(nameof(Changes));
        }

    }

现在在与上面相同的视图中,我还有一些控制绑定到CurrentToner的属性。

<TextBox Style="{StaticResource TextBoxStyle}" Grid.Row="0" Grid.Column="1" Text="{Binding CurrentToner.Name}"></TextBox>
        <TextBox Style="{StaticResource TextBoxStyle}" Grid.Row="1" Grid.Column="1" Text="{Binding CurrentToner.Level}" ></TextBox>
        <ComboBox  Grid.Row="2" Grid.Column="1" SelectedValue="{Binding CurrentToner.TonerType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding TonerTypes, Mode=OneWay}" DisplayMemberPath="Name"></ComboBox>
        <TextBox Style="{StaticResource TextBoxStyle}" Grid.Column="1" Grid.Row="3" Text="{Binding CurrentToner.Note}" AcceptsReturn="True" VerticalScrollBarVisibility="Visible"></TextBox>

现在我可以在ListView中单击arround,我的TextControls将按照预期更新。 但是,如果我重新加载Observable Collection中的数据,将不再在Combobox中更新所选项目(数据仍然可用,我使用调试器检查,Combobox仍然可以在CurrentToner中设置TonerType) 我使用Entity Framework从SQL Server重新加载数据:

private void ReloadToner()
    {
        Toner.Clear();
        using (var uw = new UnitOfWork(new Gritly_DEVEntities1()))
        {
            Toner.AddRange(uw.Toners.GetAll());

        }

    }

如何实施我的重新加载逻辑以再次更新所选项目? (它在重新加载之前工作)

编辑:屏幕截图显示它应该如何以及它不是如何。 it should be like this not like this

EDIT2:我找到了答案,我必须在TonerType上覆盖Equals()以根据Id而非Adress进行比较

1 个答案:

答案 0 :(得分:0)

如果您重新加载数据,那么您的收藏中会有新对象 我错过了那个对象类型,如果它在那里但是无论如何让我们称之为Toner。 确保碳粉具有唯一标识的东西,如ID。 如果你看一下Toner对象,你可能可以解决哪个是旧的当前对象,但计算机是非常文字的。他们需要你告诉他们他们应该如何知道碳粉是一种特定的碳粉而不是任何旧油墨。

当您要重新读取数据时,请将该ID保存在私有变量中。 阅读数据 构建您的可观察集合。 使用id上的某些linq匹配查找相应的条目 类似的东西:

Toner newSelectedToner = Toners.Where(x=>x.ID = lastSelectedID).FirstOrDefault();

顺便说一下,这只是空气代码。 将CurrentToner设置为该实例 此外,在您的碳粉上覆盖等于使用ID。