2014-07-13 3 views
0

저는 ComboBox (WPF 4.0)를 사용하여 편집기 응용 프로그램에 대한 사용자 정의 단락 스타일을 표시하고 있습니다. 콤보 상자 두 개의 열이 있습니다ComboBox SelectedItem이 업데이트되지 않습니다.

(1) 단락 스타일의 포맷되지 않은 이름
(2) 텍스트 "abcABC123는"일부 속성의 첫 번째 열에서 단락 스타일에 따라 형식이

이러한 공용 속성은
_NameUI
_ResourceKey_background
_ResourceKey_foreg

_NameInternal : (마지막 3 ResourceKeys를 포함하는 더 ResourceKeys하지만 변수 없음) 사용자 정의 단락 스타일 클래스의 round
_ResourceKey_fontFamily

문제 : ComboBox에 SelectedItem이 표시됩니다. 대화 상자를 열면 SelectedItem (Background, Foreground, FontFamily)의 3 가지 바인딩 속성 중 하나 이상을 변경하고 ComboBox의 SelectedItem이 업데이트되지 않습니다. 하지만 내려 놓으면 새 서식이 표시됩니다.

Xaml에서 C# 대신이 문제를 해결할 수있는 방법이 있습니까? 여기

public class _2ResourceLookupConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return App.Current.TryFindResource(value); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return Binding.DoNothing; 
    } 
} 

는 사용자 정의 단락 스타일에 대한 2 개 클래스입니다 : 뒤에

<Window.Resources> 
    <local2:_2StylesPara x:Key="_2stylesPara" /> 
    <CollectionViewSource x:Key="_collectionViewSource_stylesPara" Source="{StaticResource _2stylesPara}"> 
     <CollectionViewSource.SortDescriptions> 
      <!-- Requires 'xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"' declaration. --> 
      <scm:SortDescription PropertyName="_NameUI" Direction="Ascending"/> 
     </CollectionViewSource.SortDescriptions> 
    </CollectionViewSource> 
</Window.Resources> 

<ComboBox Name="_cbStylesPara" HorizontalAlignment="Left" 
      ItemsSource="{Binding Source={StaticResource _collectionViewSource_stylesPara}}" 
      SelectedValuePath="_NameInternal" IsSynchronizedWithCurrentItem="True" > 
    <ComboBox.Resources> 
     <local2:_2ResourceLookupConverter x:Key="_resourceLookupConverter"/> 
    </ComboBox.Resources> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="100"/> 
        <ColumnDefinition Width="100" /> 
       </Grid.ColumnDefinitions> 
       <Grid.RowDefinitions> 
        <RowDefinition /> 
       </Grid.RowDefinitions> 
       <TextBlock Text="{Binding _NameUI}" Grid.Column="0" VerticalAlignment="Center" /> 
       <TextBlock Grid.Column="1" Text="abcABC123" Margin="3,0,0,0" 
          Background="{Binding _ResourceKey_background, Converter={StaticResource _resourceLookupConverter}}" 
          Foreground="{Binding _ResourceKey_foreground, Converter={StaticResource _resourceLookupConverter}}" 
          FontFamily="{Binding _ResourceKey_fontFamily, Converter={StaticResource _resourceLookupConverter}}"/> 
      </Grid> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

코드 내가 제대로 이해하면

public class _2StylesPara : ObservableCollection<_2StylePara> 
// ObservableCollection implements INotifyPropertyChanged 
{ 
    public _2StylesPara(){} 
} 

public class _2StylePara 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    // This method is not reached if Background, Foreground or FontFamily changes 
    private void SetValue<T>(ref T property, T value, string propertyName = null) 
    { 
     if (object.Equals(property, value) == false) 
     { 
      property = value; 

      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

    private string _nameInternal = string.Empty; 
    private string _nameUI = string.Empty; 
    private string _resourceKey_background = string.Empty; 
    private string _resourceKey_foreground = string.Empty; 
    private string _resourceKey_fontFamily = string.Empty; 
    private string _resourceKey_nameUI = string.Empty; 
    private string _resourceKey_style = string.Empty; 
    private Style _style = null; 
    private ResourceDictionary _valuesRD = null; 
    private string _pathToValuesRD = string.Empty; 


    public string NameInternal 
    { 
     get { return this._nameInternal; } 
     set { SetValue(ref this._nameInternal, value); } 
    } 

    public string NameUI 
    { 
     get { return this._nameUI; } 
     set { SetValue(ref this._nameUI, value); } 
    } 

    public string ResourceKey_background 
    { 
     get { return this._resourceKey_background; } 
     set { SetValue(ref this._resourceKey_background, value); } 
    } 

    public string ResourceKey_foreground 
    { 
     get { return this._resourceKey_foreground; } 
     set { SetValue(ref this._resourceKey_foreground, value); } 
    } 

    public string ResourceKey_fontFamily 
    { 
     get { return this._resourceKey_fontFamily; } 
     set { SetValue(ref this._resourceKey_fontFamily, value); } 
    } 

    public string ResourceKey_nameUI 
    { 
     get { return this._resourceKey_nameUI; } 
     set { SetValue(ref this._resourceKey_nameUI, value); } 
    } 

    public string ResourceKey_style 
    { 
     get { return this._resourceKey_style; } 
     set { SetValue(ref this._resourceKey_style, value); } 
    } 

    public Style Style 
    { 
     get { return this._style; } 
     set { SetValue(ref this._style, value); } 
    } 

    public ResourceDictionary ValuesRD 
    { 
     get { return this._valuesRD; } 
     set { SetValue(ref this._valuesRD, value); } 
    } 

    public string PathToValuesRD 
    { 
     get { return this._pathToValuesRD; } 
     set { SetValue(ref this._pathToValuesRD, value); } 
    } 


    // Constructor 
    public _2StylePara(Style sty, string styleNameInternal, string styleNameUI, string resourceKey_style, string resourceKey_nameUI, 
         string resourceKey_foreground, string resourceKey_background, string resourceKey_fontFamily, 
         ResourceDictionary valuesRD, string pathToValuesRD) 
    { 
     _style = sty; 
     _nameInternal = styleNameInternal;     // [ "_sty001" ] 
     _nameUI = styleNameUI;        // [ "Standard" ] 

     _resourceKey_style = resourceKey_style;    // [ "_stylePara001" ] 
     _resourceKey_nameUI = resourceKey_nameUI;   // [ "_nameUi001 ] 
     _resourceKey_foreground = resourceKey_foreground; // [ "_brush_textcolor001" ] 
     _resourceKey_background = resourceKey_background; // [ "_brush_backcolor001" ] 
     _resourceKey_fontFamily = resourceKey_fontFamily; // [ "_fontFamily001" ] 

     _valuesRD = valuesRD;        // This ResourceDictionary contains all style values 
     _pathToValuesRD = pathToValuesRD;     // [ "...\Resources\1ParaStyleValuesRD001.xaml" ] 
    } 
} 
+0

사용자 정의 단락 스타일 클래스에 INotifyPropertyChanged가 구현 되었습니까? –

답변

0

는 _ResourceKey_background 및 기타 속성의 속성입니다 당신의 _2sytlesPara 컬렉션에 포함 된 사용자 정의 단락 스타일 클래스. 사용자가 경험하는 동작은 백그라운드에서 이러한 속성을 변경하면보기가 업데이트되지 않습니다.

이 경우 사용자가 모델 (일명 UDF 스타일 클래스 인스턴스 중 하나)을 업데이트하면 바인딩에 대한 업데이트가 업데이트되어야합니다. 모델에 의해 트리거되어야하는 INotifyPropertyChanged.PropertyChanged 이벤트에 의해 수행됩니다.

바인딩이 자동으로 다른 방식으로 작동하므로보기에서 변경하면 모델이 업데이트됩니다. 알림

표준 속성 패턴은 다음과 같습니다

class Model : INotifyPropertyChanged 
{ 
    private int _Name = default(int); 
    public int Name 
    { 
     get { return _Name; } 
     set 
     { 
      SetValue(ref this._Name, value); 
     } 
    } 

    private void SetValue<T>(ref T property, T value, [CallerMemberName]string propertyName = null) 
    { 
     if (object.Equals(property, value) == false) 
     { 
      property = value; 

      if (this.PropertyChanged != null) 
      { 
       this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

내가 문제를 이해하고 내가 도움이 될 수 있기를 바랍니다.

는 UPDATE :

IObservableCollection 유일한 컬렉션의 추가 및 삭제에 대해 mechanizm 바인딩 알려줍니다. 아이템의 중첩 된 속성 값의 변경은 여전히 ​​자동으로 반영되지 않습니다.

나는 다음과 같은 수정을 시도하는 것이 좋습니다 것입니다 코드에 관한 모든의

첫째, 나는 밑줄 공공 propertry 이름을 시작 권하고 싶지 않다. MS 명명 규칙에 따르면 밑줄로 시작하는 이름은 대개 개인용 백업 필드입니다.

그래서, 같은 해당 속성 변경 : 속성에 바인딩을 변경 또한

private string _ResourceKey_nameUI = string.Empty; 
public string ResourceKey_nameUI 
{ 
    get { return this._ResourceKey_nameUI; } 
    set { SetValue(ref this._ResourceKey_nameUI, value); } 
} 

을 :

<TextBlock Grid.Column="1" Text="abcABC123" Margin="3,0,0,0" 
Background="{Binding ResourceKey_background, Converter={StaticResource _resourceLookupConverter}}" 
Foreground="{Binding ResourceKey_foreground, Converter={StaticResource _resourceLookupConverter}}" 
FontFamily="{Binding ResourceKey_fontFamily, Converter={StaticResource _resourceLookupConverter}}"/> 

UPDATE 2 개

WPF 바인딩 검사를 바인딩 모델 인스턴스 경우 INotifyPropertyChanged 인터페이스를 구현하십시오. 로 클래스 선언을 수정하십시오 : 당신이 백그라운드에서 값을 변경할 때

public class _2StylePara : INotifyPropertyChanged 
{ 
//... 
} 

는 또한, 당신은 등록하지 후원 필드를 사용합니다. 따라서 NameUI를 변경하면 SetValue 메서드가 호출되어 TextBlock을 새로 고치기 위해 바인딩에 알립니다. 바인딩은 또한 배킹 필드가 아닌 속성을 가리켜 야합니다.

따라서 : Text = "{Binding NameUI}"NOT 텍스트 = "{Binding _NameUI}" 도와 주면 답변으로 표시하십시오. 감사.

+0

죄송합니다. ObservableCollection이 INotifyPropertyChanged를 구현하고 첫 번째 게시물을 업데이트 한 것으로 나타났습니다. – Pollitzer

+0

마지막 제안을 시도했지만 불행히도 동일한 결과가 발생하지 않습니다. – Pollitzer

+0

속성 값을 변경 한 곳에서 코드를 게시 할 수 있습니까? –

관련 문제