2011-08-12 45 views
1

我有一个使用ObservableCollection作为源的组合框。我已绑定作为源如下绑定到ObservableCollection的组合框不会更新

<ComboBox IsEditable="False" 
      SelectedIndex="{Binding Source={x:Static Properties:CollectionControl.Settings}, Path=SamplingPeriodIndex, Mode=TwoWay}" 
      SelectionChanged="onPeriodControlSelectionChanged" 
      Name="PeriodControl" 
      ItemsSource="{StaticResource test}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding SamplingPeriod}" Visibility="{Binding Converter={StaticResource TrackVis}, ConverterParameter=GroupIndex}"/> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

TrackVis是确定如果元素是可见的或折叠,这取决于已INotifyPropertyChanged的实现的外部特性的转换器。

一切正常,第一次ComboBox显示,但组合框永远不会刷新,以反映变化。我一定错过了一些东西,但截至目前,我所尝试过的一切都失败了。

这里是转换器

public class IsVisibleConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
     var tempObj = (SamplingPeriods) value; 
     if (tempObj.GroupIndex >= CollectionControl.Settings.SamplingFrequencyIndex) 
     { 
      return Visibility.Visible; 
     } 

     return Visibility.Collapsed; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, 
     System.Globalization.CultureInfo culture) 
    { 
      throw new NotImplementedException(); 
    } 
} 

另外的代码,这里是收集

public class PeriodsCollection : ObservableCollection<SamplingPeriods> 
{ 
    public PeriodsCollection() 
    { 
     Add(new SamplingPeriods("1/16 of a second", 13)); 
     Add(new SamplingPeriods("1/8 of a second", 12)); 
     Add(new SamplingPeriods("1/4 of a second", 11)); 
     Add(new SamplingPeriods("1/2 of a second", 10)); 
     Add(new SamplingPeriods("1 second", 9)); 
     Add(new SamplingPeriods("2 seconds", 8)); 
     Add(new SamplingPeriods("4 seconds", 7)); 
     Add(new SamplingPeriods("8 seconds", 6)); 
     Add(new SamplingPeriods("16 seconds", 5)); 
     Add(new SamplingPeriods("32 seconds", 4)); 
     Add(new SamplingPeriods("64 seconds", 3)); 
     Add(new SamplingPeriods("128 seconds", 2)); 
     Add(new SamplingPeriods("256 seconds", 1)); 
     Add(new SamplingPeriods("512 seconds", 0)); 
    } 
} 

public class SamplingPeriods 
{ 
    public SamplingPeriods(string samplingPeriod, int groupIndex) 
    { 
     SamplingPeriod = samplingPeriod; 
     GroupIndex = groupIndex; 
    } 

    public string SamplingPeriod { get; private set; } 
    public int GroupIndex { get; private set; } 
} 

的想法是,所选择的采样频率限制了可用的采样周期。采样频率指数范围从0到11.例如,如果采样索引是9,则只有有效采样周期将具有GroupIndex> = 9.其他采样周期将被折叠。

+0

为什么静态资源,而不是简单地命名的财产? – sll

+0

对TrackVis或selectedindex或两者的更改? – Tyrsius

+0

当问这样的问题时,确实非常重要的是要具体说明什么不是更新。将新项目添加到集合时,新项目是否不会出现在“ComboBox”中?当您更改代码中的绑定属性时,“SelectedIndex”不会更新吗?具体而言,现在和现在都没有发生什么? –

回答

0

您正在尝试跟踪采样频率指数。那么您必须将绑定到具有此属性的对象并实现INotifyPropertyChanged.Or,正如我已经说过的那样,将此事件传播到作为绑定源的对象,并在其上引发正确的属性更改。否则,绑定引擎将不知道该属性的变化。 绑定到CollectionControl.SettingsPath = SamplingFrequencyIndex

+0

当我添加path = propertyWithChangeNotification时,TrackVis转换器永远不会被调用。 –

+0

通过财产与更改通知我的意思是改变你的情况的财产。这个属性是否驻留在“测试”对象中? – objectbox

+0

在VisualStudio中,转到视图>输出。当你调试你的应用程序时,输出中是否有绑定错误? – objectbox

0

SamplingPeriods需要实现INotifyPropertyChanged的,你需要调用NotifyPropertyChanged上设定。我会在CollectionControl.Settings.SamplingFrequencyIndex上保留你期望从你的代码中得到的值,并且不清楚你设置的位置。当你改变SamplingFrequencyIndex时,你需要在ObservabaleCollection上调用NotifyPropertyChanged来强制刷新。有一个更好的方法来做到这一点。更改SamplingPeriods并将参考传递给SamplingFrequencyIndex,以便更改要更改的实际对象。

CollectionViewSource.GetDefaultView(lbFields.ItemsSource).Refresh(); 
+0

你让我和安倍一起思考,我决定采用不同的方法。我创建了一个CollectionViewSource和一个过滤器。然后,当SamplingFrequencyIndex事件被触发时,我强制CollectionViewSource的view.refresh。很棒!感谢两人为我设定这条道路。 –

0

如果您的期间和您的频率都在同一个班级举行,为什么不公开可用期的列表呢?然后,您可以使用的CollectionView来筛选集合,而不是转换器&知名度:

// initialize in your constructor 
public PeriodsCollection AvailablePeriods { get; private set; } 

public int SamplingFrequencyIndex 
{ 
    get { return samplingFrequencyIndex; } 
    set 
    { 
     samplingFrequencyIndex = value; 
     RaisePropertyChanged("SamplingFrequencyIndex"); 
     var view = CollectionViewSource.GetDefaultView(AvailablePeriods) as ListCollectionView; 
     view.Filter = o => ((SamplingPeriod)o).GroupIndex >= value; 
    } 
} 
相关问题