2017-08-07 22 views
0

私はいくつかのインタラクティブなUI要素を持つビューを持つアプリケーションを持っています。また、DispatcherTimerにUIの更新を10秒ごとに実行しています。私は、ダイナミックグリッドの子の数に基づいて、子要素を異なる方法で配置するカスタムの動的グリッドを作成しました。(WPF/C#)DispatcherTimerでループを更新するUI

しかし、私には問題があります。タイマーが起動すると、要素を更新するときに動的グリッドがループに巻き込まれてしまい、その理由がわかりません。ここでは、コードの簡易版であり、それが不十分であるなら、私に教えてください:

MainWindow.xaml.cs

public MainWindow() 
    { 
     InitializeComponent(); 

     main = new MainView(pollCollectionMain); 


     RefreshTimer = new DispatcherTimer(); 
     RefreshTimer.Tick += new EventHandler(OnTimedEvent); 
     RefreshTimer.Interval = new TimeSpan(0, 0, 10); 
     RefreshTimer.Start(); 

    } 

    private void OnTimedEvent(object sender, EventArgs e) 
    { 
     //The Polling class has a variable output 
     pollObj = new Polling(); 
     pollCollectionMain = pollObj.PollingCollection; 
     main = new MainView(pollCollectionMain); 
    } 

main.cs

public MainView(ObservableCollection<PollingData> pollLocal) 
    { 
     dynGrid = new DynamicGrid(); 
     p = pollLocal; 

     for (int i = 0; i < p.Count; i++) 
     { 
      //Making some new controls 
      //ControlGrid is just a Grid with mouse functionality 
      mainControlGrid = new ControlGrid(); 
      mainControlGrid.Children.Add(someControl); 
      dynGrid.Children.Add(mainControlGrid); 
     } 

    } 

DynamicGrid()、無限ループが発生する

public DynamicGrid() 
    { 

     _currentChildrenCount = 0; 

     //The following is the infinite loop 
     LayoutUpdated += (s, e) => 
     { 
      if (Children?.Count != _currentChildrenCount) 
      { 
       _currentChildrenCount = (Children != null) ? Children.Count : 0; 
       OnNumberOfItemsChangedImpl(); 
      } 
     }; 
    } 

答えて

0

WPFでこのようなレイアウトを管理しないでください。 WPFには、これを管理するための組み込みの方法があります。

public class YourPanel : Panel { 

    protected override Size MeasureOverride(Size availableSize) { 
     if (InternalChildren.Count == 0) return new Size(0, 0); 
     //Measure each children's size and then compute and return the size the panel needs to display correctly 

     foreach(UIElement children in InternalChildren) { 
      children.Measure(sizeYouWantToGiveToTheElement); 
     } 

     return totalSizeYourPanelNeeds; 
    } 

    protected override Size ArrangeOverride(Size finalSize) { 
     if (InternalChildren.Count == 0) return new Size(0, 0); 

     //Arrange each element in the panel according to your own rules 
     for (int i = 0; i < InternalChildren.Count; i++) { 
      UIElement children = InternalChildren[i]; 

      //Arrange the panel's children at the position you want and with the size you want 
      children.Arrange(new Rect(childrenPosition, childrenSize)); 
     } 

     return finalSize; 
    } 
} 

これを行わない限り、不要な更新を行い、ディスパッチャを妨害します。

あなたはItemsControlにであなたのパネルを使用することができます。

<ItemsControl ItemsSource="{Binding Path=YourItems, Mode=OneWay}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <YourPanel/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

あなたはカスタムパネルhereまたは例えばhereに関する詳細な情報を見つけることができます。

+0

です。グリッドを使用する場合とパネルを使用する場合の主な違いは何ですか? – Michael

+0

@MichaelグリッドはPanelの実装です – nkoniishvt