2016-10-05 88 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