2010-08-19 67 views
3

我使用的是儘管在XAML將孩子形式綁定到Children.Count

{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=Rows} 

的結合,當我在轉換器斷裂,​​值始終爲0

我假設正在進行的是,直到這個綁定被調用之後纔會添加子項。

我還假設結合被打破後,它被稱爲曾經因爲.Count之間是一個只讀屬性(我有,我必須在屬性添加一個空二傳手保持結合和愚弄之前,類似的問題WPF),因此一旦添加子項,綁定不會更新。

不過,我卡在那裏你想出瞭解決問題的辦法,並使其發揮作用的位... =/

<UniformGrid x:Name="MyUniformGrid" 
    Rows="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=R}" 
    Columns="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=C}"> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    </UniformGrid> 

感謝, RABIT

回答

8

這是因爲UIElementCollectionChildren屬性的類型)在添加或刪除新項目時不會引發通知,因此不會刷新綁定

但是,您可以創建自己的自定義UniformGrid,並且o使用CreateUIElementCollection屬性來創建繼承UIElementCollection並實現INotifyCollectionChanged的自定義集合的實例。

這是一個基本的實現:

ObservableUIElementCollection

public class ObservableUIElementCollection : UIElementCollection, INotifyCollectionChanged, INotifyPropertyChanged 
{ 
    public ObservableUIElementCollection(UIElement visualParent, FrameworkElement logicalParent) 
     : base(visualParent, logicalParent) 
    { 
    } 

    public override int Add(UIElement element) 
    { 
     int index = base.Add(element); 
     var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, element, index); 
     OnCollectionChanged(args); 
     OnPropertyChanged("Count"); 
     OnPropertyChanged("Item[]"); 
     return index; 
    } 

    public override void Clear() 
    { 
     base.Clear(); 
     OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
     OnPropertyChanged("Count"); 
     OnPropertyChanged("Item[]"); 
    } 

    public override void Insert(int index, UIElement element) 
    { 
     base.Insert(index, element); 
     var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, element, index); 
     OnCollectionChanged(args); 
     OnPropertyChanged("Count"); 
     OnPropertyChanged("Item[]"); 
    } 

    public override void Remove(UIElement element) 
    { 
     int index = IndexOf(element); 
     if (index >= 0) 
     { 
      RemoveAt(index); 
      var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, element, index); 
      OnCollectionChanged(args); 
      OnPropertyChanged("Count"); 
      OnPropertyChanged("Item[]"); 
     } 
    } 

    public override UIElement this[int index] 
    { 
     get 
     { 
      return base[index]; 
     } 
     set 
     { 
      base[index] = value; 
      var args = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, index); 
      OnCollectionChanged(args); 
      OnPropertyChanged("Item[]"); 
     } 
    } 

    public event NotifyCollectionChangedEventHandler CollectionChanged; 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) 
    { 
     var handler = CollectionChanged; 
     if (handler != null) 
      handler(this, e); 
    } 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     var handler = PropertyChanged; 
     if (handler != null) 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

MyUniformGrid

public class MyUniformGrid : UniformGrid 
{ 
    protected override UIElementCollection CreateUIElementCollection(FrameworkElement logicalParent) 
    { 
     return new ObservableUIElementCollection(this, logicalParent); 
    } 
} 

XAML

<local:MyUniformGrid x:Name="MyUniformGrid" 
    Rows="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=R}" 
    Columns="{Binding RelativeSource={RelativeSource Self}, Path=Children.Count, Converter={StaticResource CountToDimensionConverter}, ConverterParameter=C}"> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
    <Button Content="Hello, World!" /> 
</local:MyUniformGrid>