SelectedItem更改细节,然后绑定到先前选定的项目

时间:2012-06-28 14:09:52

标签: c# wpf data-binding binding

我有区域形式的一些分层数据,其中包含系统,其中包含入口 我的WPF应用程序有一个行程列表,其中入口作为属性。 UI是一个拆分窗口,其中包含ListControl和绑定到ListView.SelectedItem属性的“详细信息”控件,如下所示:(为简洁起见编写代码,仅显示相关部分)

<local:ListView x:Name="listView"/>
<local:DetailsView DataContext="{Binding ElementName=listView, Path=SelectedItem}"/>

详细信息视图包含属性的ComboBox,其中包括:

<ComboBox Name="comboRegion" SelectionChanged="Region_Changed"
    ItemsSource="{Binding ElementName=main, Path=Regions, Mode=OneWay}" DisplayMemberPath="Name"
    SelectedItem="{Binding Region, Mode=OneWay}"/>
<ComboBox Name="comboSystem" SelectionChanged="System_Changed"
    ItemsSource="{Binding ElementName=main, Path=Systems, Mode=OneWay}" DisplayMemberPath="Name"
    SelectedItem="{Binding System, Mode=OneWay}"/>
<ComboBox ItemsSource="{Binding ElementName=main, Path=Entrances, Mode=OneWay}" DisplayMemberPath="Name"
    SelectedItem="{Binding Enter}"/>

Trip.Enter是我要编辑的属性,Trip.Region和Trip.System是只读的,并从Trip.Enter计算。 main.Regions,main,systems和main.Entrances是控件的本地列表,具有以下代码:

    public IEnumerable<Region> Regions { get; private set; }
    public IEnumerable<CaveSystem> Systems { get; private set; }
    public IEnumerable<Entrance> Entrances { get; private set; }

    private void Region_Changed(object sender, SelectionChangedEventArgs e)
    {
        Region = comboRegion.SelectedItem as Region;
        Systems = (region != null ? region.Systems : null);
        NotifyPropertyChanged("Systems");
    }

    private void System_Changed(object sender, SelectionChangedEventArgs e)
    {
        ... Equivalent to Region_Changed except updates Entrances ...
    }

区域列表是静态的,因此填充一次。 选择新区域后,将使用新列表重新填充“系统”列表 选择新系统时(也可以是更改区域的级联),将重新填充入口列表。

到目前为止,这么好。这按预期工作,在列表视图中选择一个行程将其详细信息绑定到组合框。更改组合框中的值,使用新列表更新相应的“较低级别”框。 最后,选择一个入口更新记录本身(列表视图适当更新)

问题是: 当我在列表视图中选择一个新记录时,新记录中的值将显示在组合框中,但也会复制到所选的最后一个记录中。

我认为问题在于,更改详细信息视图的数据上下文会导致更新所有绑定。我认为这反过来会发生,但更改所选区域会在较低级别的组合框中产生连锁反应,这也会改变。我认为他们在那时仍然与旧记录有关。

有人可以建议这样做吗?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用策略模式。不要改变你的datacontext,而是改变你的datacontext中的类。在这个内部类中,您可以使用工作逻辑,但您的datacontext将是相同的。例如:

public interface InnerDataContext
{
   public CaveSystem System{get;}
}

public class DataContext
{
   private InnerDataContext dc;

   public CaveSystem
   { get{ return dc.System; }}
}

您可以在需要时更改内部datacontext,并且它不会抛出更新值。

答案 1 :(得分:0)

好的,找到了解决方案! 我将绑定更改为

UpdateSourceTrigger =引发LostFocus

这意味着只有当用户在组合框中选择新值时才会更新对象,而不是在组合框由于更改数据上下文而更新时。