检测到布局周期.布局无法完成.检测到布局周期.布局无法完成

  • 本文关键字:布局 周期 c# xaml uwp
  • 更新时间 :
  • 英文 :


我知道有一些问题与同一头行,但我找不到任何对我有用的答案。

进入XML文件Triple ListBox,该框是由3个内部可观察集合构建的。(包含包含int列表的字段列表的寄存器列表。

XAML:

<ScrollViewer HorizontalScrollBarVisibility="Auto">  
        <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
            <Grid.RowDefinitions>
                <RowDefinition Height="60"/>
                <RowDefinition Height="*"/>
                <RowDefinition MaxHeight="50"/>
            </Grid.RowDefinitions>
            <ListBox x:Name="RegistersListView" ItemsSource="{x:Bind registersList}" Grid.Row="1">
                <ListBox.ItemTemplate>
                    <DataTemplate x:DataType="structures:Register">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <TextBlock Text="{x:Bind name}" Grid.Row="0" />
                            <ListBox x:Name="FieldsListView" ItemsSource="{x:Bind reg_fields}" Grid.Row="1">
                                <ListBox.ItemTemplate>
                                    <DataTemplate x:DataType="structures:Field">
                                        <StackPanel>
                                            <TextBlock Text="{x:Bind name}"/>
                                            <ListBox x:Name="BitsListView" ItemsSource="{x:Bind bitsList}">
                                                <ListBox.ItemsPanel>
                                                    <ItemsPanelTemplate>
                                                        <StackPanel Orientation="Horizontal"/>
                                                    </ItemsPanelTemplate>
                                                </ListBox.ItemsPanel>
                                            </ListBox>
                                        </StackPanel>
                                    </DataTemplate>
                                </ListBox.ItemTemplate>
                                <ListBox.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <StackPanel Orientation="Horizontal" />
                                    </ItemsPanelTemplate>
                                </ListBox.ItemsPanel>
                            </ListBox>
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>
            </ListBox>
        </Grid>
    </ScrollViewer>

但是,当我的数据在〜60寄存器中时,我会收到此消息:

检测到的布局周期。布局无法完成。布局周期 检测到。布局无法完成。

不知道这是关于什么的。调试器也没有信息。

我几乎确定它与ScrollViewer有关,因为当将其删除时,也不例外。但是我需要这个ScrollViewer,因此也欢迎使用ScrollViewer做某事的任何想法。谢谢。

编辑:

类是:

    public class Field : INotifyPropertyChanged
    {
        public string name;
        public int offset;
        public int length;
        public string description;
        private UInt64 _value;
        private ObservableCollection<int> bitsList = new ObservableCollection<int>();
        public ObservableCollection<int> BitsList
        {
            get
            {
                return new ObservableCollection<int>(bitsList);
            }
            set
            {
               //todo
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public Field(string _name)
        {
            name = _name;
        }
        override public string ToString()
        {
            return name;
        }
        public void Value(UInt64 value)
        {
            _value = value;
#pragma warning disable CS4014
            Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                for (int i = 0; i < length; i++)
                {
                    bitsList.Add(Convert.ToInt32(value & 1));
                    value = value >> 1;
                }
                OnPropertyChanged("BitsList");
            });
#pragma warning restore CS4014
        }
    }
    public class Register
    {
        public string name;
        public UInt64 _deafult_value;
        public UInt64 value;
        public int offset;
        public int index;
        public string description;
        public int register_size;
        public ObservableCollection<Field> reg_fields = new ObservableCollection<Field>();
        public Register(string _name)
        {
            name = _name;
        }
    }

填充寄存器列表太复杂了,无法在此处添加,但为了简化:

    public ObservableCollection<Register> registersList = new ObservableCollection<Register>();
    private void InnerDataCreator()
        {
            Instances instances = new Instances();
            registersList = instances.PopulateRegistersData();
        }
public ObservableCollection<Register> PopulateRegistersData()
        {
            const int REG_AMOUNT = 100;
            const int REG_SIZE = 32;
            ObservableCollection<Register> registers = new ObservableCollection<Register>();

            for (int regIndex = 0; regIndex < REG_AMOUNT; regIndex++)
            {
                Register register = new Register("reg_" + regIndex.ToString());
                register.description = "register description _***_ " + regIndex.ToString();
                register.register_size = REG_SIZE;
                ObservableCollection<Field> fields = new ObservableCollection<Field>();
                int offset = 0;
                /* 4 fields in each register */
                for (int fieldNum = 0; fieldNum < 4; fieldNum++)
                {
                    string fieldName;
                    if(regIndex < REG_AMOUNT / 2)
                    {
                        fieldName = "reg_" + regIndex.ToString() + " Field_" + fieldNum.ToString();
                    }
                    else
                    {
                        fieldName = "################ reg_" + regIndex.ToString() + " Field_" + fieldNum.ToString() + "###################";
                    }
                    Field field = new Field(fieldName);
                    field.description = "field description. reg: " + regIndex.ToString() + ". field: " + fieldNum.ToString();
                    field.length = 8;
                    field.offset = offset;
                    field.Value(BitConverter.GetBytes(170)[0]); /* 10101010 */
                    register.reg_fields.Add(field);
                    offset += field.length;
                }

                registers.Add(register);
            }
            return registers;
        }
    }

我通过foreach循环填充了一些StackLayout。它们每个都包含在固定高度的ScrollViewer中。

当内容太大时,它开始随着"检测到的布局周期"错误崩溃。

我将StackLayout s更改为Grid s,最后解决了这个非常烦人的问题。

更新:1年后,我的应用程序再次遭受了问题。我通过在有问题的网格视图中添加VerticalAlignment属性来修复它...

更新2 :4年后,我的问题又回来了,在同一项目中……事实证明这是一个Microsoft错误太大了。请参阅此处:https://github.com/microsoft/microsoft-ui-xaml/issues/6218。解决方案?更新框架...但是即使在100%的情况下也无法解决。

我使用了listbox内置的scrollviewer而不是scrollviewer布局,它似乎可以修复错误。

<ListBox x:Name="RegistersListView" ItemsSource="{x:Bind registersList}" Grid.Row="1" 
             ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollMode="Enabled">

性能对于超过50个对象仍然不好,但这比异常好。使用ListView而不是ListBox性能时,则没有显示内置的ScrollViewer。所以我不将这个答案标记为可接受的。

listView版本:

<ListView x:Name="RegistersListView" ItemsSource="{x:Bind registersList}" Grid.Row="1"
             ScrollViewer.HorizontalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollMode="Enabled"

最新更新