我有一个应用程序,我有一个带有多个交互式UI元素的View。另外,我有一个DispatcherTimer每10秒运行一次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 :(得分:0)
您不应该在WPF中管理这样的布局。 WPF有一种内置的管理方式:使用Panel。
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>