2016-10-05 83 views
0

问题

我试图绑定组合框的SelectedItem到自定义类,但是当属性改变了这种不更新。 INotifyPropertyChanged已实施。ComboBox中选定项目没有更新

DataContext的

DataContext的是其中包含许多属性的自定义类,但这样的一个提取物是以下。你可以看到它实现了INotifyPropertyChanged,这在两个属性发生改变时被调用。

public class BctsChange : INotifyPropertyChanged 
{ 
    #region declarations 
    private byContact _Engineer; 

    public byContact Engineer 
    { 
     get { return _Engineer; } 
     set 
     { 
      _Engineer = value; 
      NotifyPropertyChanged("Engineer"); 
      OnEngineerChanged(); 
     } 
    } 

    private BctsSvc.DOSets _LeadingSet; 

    public BctsSvc.DOSets LeadingSet 
    { 
     get { return _LeadingSet; } 
     set { _LeadingSet = value; NotifyPropertyChanged("LeadingSet"); } 
    } 
    #endregion 

    #region INotify 
    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged(String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    #endregion 

    public BctsChange() 
    { 
     Engineer = new byContact(Environment.UserName); 
    } 

    private void OnEngineerChanged() 
    { 
     if (Engineer != null) 
     { 
      BctsSvc.DOSets leadSet = GetLeadingSetFromDeptCode(Engineer.DeptCode); 

      if (leadSet == null) return; 
      LeadingSet = leadSet; 
     } 
    } 


    private static BctsSvc.DOSets GetLeadingSetFromDeptCode(string DeptCode) 
    { 
     BctsSvc.BctsServiceSoapClient svc = new BctsSvc.BctsServiceSoapClient(); 
     BctsSvc.DOSets setX = svc.GetSetFromDeptCode(DeptCode); 
     return setX; 
    } 
} 

的窗口XAML

我把窗户上的几个控制,但为了保持代码的简单,我相信下面的提取物就足够了。

<Window x:Class="MyNamespace.wdSubmit" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:my="clr-namespace:MyNamespace" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      x:Name="ucReqForm" 
     Title="wdSubmit" > 
    <StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">   
     <GroupBox Header="Engineer Details" Name="grpOwnerDetails" > 
      <StackPanel Orientation="Vertical"> 
       <Grid VerticalAlignment="Top"> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*"/> 
         <ColumnDefinition Width="35"/> 
        </Grid.ColumnDefinitions> 
        <Label Content="{Binding Engineer.FullName, FallbackValue='Please select an engineer by clicking →', Mode=OneWay}" Margin="5,0" IsEnabled="True" FontStyle="Italic" /> 
        <Button Content="{StaticResource icoSearch}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Column="1" Height="23" Name="btnSelectEngineer" Margin="0,0,5,0" HorizontalAlignment="Stretch" ToolTip="Search for an engineer responsible" Click="btnSelectEngineer_Click" /> 
       </Grid> 

       <ComboBox Height="23" x:Name="ddSet2" Margin="5,0" ItemsSource="{Binding LeadingSets, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" SelectedItem="{Binding LeadingSet, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}" > 
        <ComboBox.ItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding SetName}" ToolTip="{Binding HelpInfo}"/> 
         </DataTemplate> 
        </ComboBox.ItemTemplate> 
       </ComboBox> 
       <my:LabelledDropdown Height="23" x:Name="ddSet" Margin="5,0" ItemsSource="{Binding LeadingSets, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" SelectedItem="{Binding LeadingSet, Mode=TwoWay,NotifyOnTargetUpdated=True,NotifyOnSourceUpdated=True}" Label="e.g. BodyHardware"> 
        <my:LabelledDropdown.ItemTemplate> 
         <DataTemplate> 
          <TextBlock Text="{Binding SetName}" ToolTip="{Binding HelpInfo}"/> 
         </DataTemplate> 
        </my:LabelledDropdown.ItemTemplate> 
       </my:LabelledDropdown> 
      </StackPanel> 
     </GroupBox> 
    </StackPanel> 
</Window> 

上述提取物中含有:

  • 包含联系人的名称的Label,以及一键查找联系人,势必包含部门Engineer
  • 一个ComboBoxFullName在公司内部,绑定到ObservableCollection<DOSets>,其中包含部门列表
  • 两个ComboBox es,一个是自定义一个和另一个是暂时的,以确保错误不在控制之内。这些数据绑定到LeadingSet

窗口代码隐藏

在后面的代码我设置的DataContext到CurrentChange。当用户想要选择不同的Engineer时,这将更新CurrentChange中工程师所选的部门。

当用户更改工程师时,工程师的数据绑定会更新,但所选部门(领导集)不是。

//Usings here 

namespace MyNamespace 
{ 
    public partial class wdSubmit : Window, INotifyPropertyChanged 
    { 
     private BctsSvc.BctsServiceSoapClient svc; 

     private BctsChange _CurrentChange; 

     public BctsChange CurrentChange 
     { 
      get { return _CurrentChange; } 
      set { _CurrentChange = value; OnPropertyChanged("CurrentChange"); } 
     } 


     private List<BctsSvc.DOSets> _LeadingSets; 
     public List<BctsSvc.DOSets> LeadingSets 
     { 
      get 
      { 
       return _LeadingSets; 
      } 
     } 


     public wdSubmit() 
     { 
      InitializeComponent(); 
      svc = new BctsSvc.BctsServiceSoapClient(); 
      _LeadingSets = svc.GetLeadSets().ToList(); 
      OnPropertyChanged("LeadingSets"); 

      this._CurrentChange = new BctsChange(); 

      this.DataContext = CurrentChange; 

      CurrentChange.PropertyChanged += new PropertyChangedEventHandler(CurrentChange_PropertyChanged); 
     } 

     void CurrentChange_PropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      OnPropertyChanged("CurrentChange"); 
      OnPropertyChanged(e.PropertyName); 
     } 

     private void btnSelectEngineer_Click(object sender, RoutedEventArgs e) 
     { 
      byContact newContact = new frmSearchEngineer().ShowSearch(); 

      if (newContact != null) 
      { 
       CurrentChange.Engineer = newContact; 
       PropertyChanged(CurrentChange, new PropertyChangedEventArgs("LeadingSet")); 
       PropertyChanged(CurrentChange.LeadingSet, new PropertyChangedEventArgs("LeadingSet")); 

      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     protected virtual void OnPropertyChanged(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) handler(CurrentChange, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

回答

0

我已经意识到这个问题可能是由于LeadingSet,返回时,工程师改变,是一个不同的实例,在ObservableCollection

+0

我不认为这是一个答案。但你可以试试这个:'LeadingSet = LeadingSets.Where(x => x.Property == leadSet.Property).FirstOrDefault();' – Pikoh

+0

尝试在你的ComboBox属性中加入IsSynchronizedWithCurrentItem =“True” – Mischo5500