2016-02-19 7 views
0

Я знаю, что есть много вопросов об этом, я гарантировал, что каждый ответ был предпринят. У меня нет большого опыта работы с WPF, и никто другой в моей команде, поэтому я уверен, что сделал глупую ошибку и не вижу ее. Я добавляю новую функцию в этот проект, который я взял на себя, и преобразовал код спагетти в начало решения MVVM. У меня есть модель, которая основана на DeSerialization документа XML и ViewModel. У них в настоящее время есть данные, которые мне нужны для UserControl. Поэтому у меня DataContext установлен в Code Behind. В этой MsClassification изначально устанавливается значение «UN». Я меняю combobox на что-то еще и использую кнопку для повторного чтения XML, который возвращает MsClassification обратно в «UN», однако View не обновляется. Интересно, что если я установил MsLoggingLevel на что-то еще и перечитал XML, он обновит оба значения.WPF-привязка не обновляется для одного объекта

XAML:

<TabItem Header="Init" HorizontalAlignment="Left" Height="25" VerticalAlignment="Top" Width="78" Margin="0" ClipToBounds="True"> 
      <Grid Background="#FFE5E5E5" ClipToBounds="True"> 
       <TreeView x:Name="AssessorToolWindow_InitTree" Margin="0" BorderThickness="0" ClipToBounds="True" DataContext="{Binding Path=VSParentReference.InitRules.Init}"> 
        <TreeViewItem Header="Excluded Files" ItemsSource="{Binding Path=MsExcludedFiles}"> 
         <TreeViewItem.ItemTemplate> 
          <DataTemplate> 
           <TreeViewItem Header ="{Binding}"/> 
          </DataTemplate> 
         </TreeViewItem.ItemTemplate> 
        </TreeViewItem> 
        <TreeViewItem Header="Included Files" ItemsSource="{Binding Path=MsIncludedFiles, Mode=TwoWay}"> 
         <TreeViewItem.ItemTemplate> 
          <DataTemplate> 
           <TreeViewItem Header="{Binding}"/> 
          </DataTemplate> 
         </TreeViewItem.ItemTemplate> 
        </TreeViewItem> 
        <TreeViewItem Header="Project Path"> 
         <TreeViewItem Header="{Binding Path=MsRootProjectDirectory, Mode=TwoWay}"/> 
        </TreeViewItem> 
        <TreeViewItem Header="Classification"> 
         <ComboBox 
          ItemsSource="{Binding Path=ClassificationLevels}" 
          SelectedValue="{Binding Path=MsClassification}" 
          IsSynchronizedWithCurrentItem="True" /> 
        </TreeViewItem> 
        <TreeViewItem Header="Log Level"> 
         <ComboBox 
          ItemsSource="{Binding Path=LoggerLevels}" 
          SelectedItem="{Binding Path=MsLogLevel}" 
          IsSynchronizedWithCurrentItem="True" 
          /> 
        </TreeViewItem> 
       </TreeView> 
      </Grid> 
     </TabItem> 

Code-за:

 [XmlArrayItem("EXC"), 
    XmlArray("ExcludedFiles")] 
    public ObservableCollection<string> MsExcludedFiles 
    { 
     get 
     { 
      return _msExcludedFiles; 

     } 
     set 
     { 
      if (value != _msExcludedFiles) 
      { 
       _msExcludedFiles = value; 
       NotifyPropertyChanged("MsExcludedFiles"); 
      } 

     } 
    } 

    [XmlArrayItem("INC"), 
    XmlArray("IncludedFiles")] 
    public ObservableCollection<string> MsIncludedFiles 
    { 
     get 
     { 
      return _msIncludedFiles; 
     } 
     set 
     { 
      if (value != _msIncludedFiles) 
      { 
       _msIncludedFiles = value; 
       NotifyPropertyChanged("MsIncludedFiles"); 
      } 
     } 
    } 

    [XmlElement(ElementName = "ProjectPath")] 
    public string MsRootProjectDirectory 
    { 
     get 
     { 
      return _msRootProjectDirectory; 
     } 
     set 
     { 
      if (value != _msRootProjectDirectory) 
      { 
       _msRootProjectDirectory = value; 
       NotifyPropertyChanged("MsRootProjectDirectory"); 
      } 
     } 
    } 

    [XmlElement(ElementName = "LogLevel")] 
    public string MsLogLevel 
    { 
     get { return _msLogLevel; } 
     set 
     { 
      if (value != _msLogLevel) 
      { 
       _msLogLevel = value; 
       NotifyPropertyChanged("MsLogLevel"); 
      }  
     } 
    } 


    [XmlElement(ElementName = "Classification")] 
    public String MsClassification 
    { 
     get 
     { 
      return classification; 
     } 
     set 
     { 
      if (value != classification) 
      { 
       classification = value; 
       NotifyPropertyChanged("MsClassification"); 
      } 
     } 
    } 
    protected virtual void NotifyPropertyChanged(string p) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(p)); 
    } 

ответ

0

Убедитесь реализовать в ViewModel INotifyPropertyChanged и установить привязку к TwoWay

{Binding Path=ClassificationLevels, Mode=TwoWay} 

Также одна вещь , ... Попробуйте использовать Fody. Это сэкономит вам массу времени. Попробуйте использовать WPF Inspector. Это дает вам больше возможностей для отладки привязок и обновления. Вы можете более подробно ознакомиться с Приложением.

+0

Fody определенно выглядит как хороший инструмент. Никогда не слышал об этом, но похоже, что это действительно может сэкономить массу времени. – mcy

+0

Я посмотрю на Фоди. ClassifcationLevels необходимо установить один раз, а затем выполнить. ClassificationLevel должен быть двухсторонним, поэтому я добавил это. Без изменений. Я реализую INotifyPropertyChanged. Один вопрос по этому вопросу и вопрос о нобе. Должен ли я реализовывать INotifyPropertyChanged во всех классах (VSParentReference.InitRules) –

+0

Да. Каждый класс, который должен быть привязан к элементу управления, должен его реализовать. Общее правило состоит в том, чтобы позволить каждой виртуальной машине реализовать его, и только VM связаны. Fody избавит вас от кучи времени. – user853710

Смежные вопросы