我有区域形式的一些分层数据,其中包含系统,其中包含入口 我的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 ...
}
区域列表是静态的,因此填充一次。 选择新区域后,将使用新列表重新填充“系统”列表 选择新系统时(也可以是更改区域的级联),将重新填充入口列表。
到目前为止,这么好。这按预期工作,在列表视图中选择一个行程将其详细信息绑定到组合框。更改组合框中的值,使用新列表更新相应的“较低级别”框。 最后,选择一个入口更新记录本身(列表视图适当更新)
问题是: 当我在列表视图中选择一个新记录时,新记录中的值将显示在组合框中,但也会复制到所选的最后一个记录中。
我认为问题在于,更改详细信息视图的数据上下文会导致更新所有绑定。我认为这反过来会发生,但更改所选区域会在较低级别的组合框中产生连锁反应,这也会改变。我认为他们在那时仍然与旧记录有关。
有人可以建议这样做吗?
答案 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
这意味着只有当用户在组合框中选择新值时才会更新对象,而不是在组合框由于更改数据上下文而更新时。