ListView 在我滑动屏幕之前不显示

分享于2022年10月08日 android c# listview maui xaml 问答
【问题标题】:ListView not displaying until I swipe the screenListView 在我滑动屏幕之前不显示
【发布时间】:2022-10-07 08:59:27
【问题描述】:

我试图在我的 .NET MAUI 应用程序中实现 StateContainer by Patrick McCurley 。 首次显示 ListView 时,它可以正常工作。 但是当状态再次改变时,ListView 不会显示,直到我滑动屏幕。

当我将任何视图元素(标签、按钮等)添加到包含 ListView 的视图时,它不会显示。但是当我将 StateContainer 与任何其他视图元素一起移动到 Grid 时,ListView 显示正确。如果 Grid 不包含 StateContainer 以外的其他元素,ListView 将无法正确显示。

我无法弄清楚这里有什么问题。带有其他视图元素的网格对我来说不是一个解决方案,因为我的页面不应该包含任何其他元素,比如 StateContainer。

这是一个重现该问题的示例:

附言我很抱歉有很多代码:) 我不知道问题出在哪里。

状态.cs

public enum States
{
    Loading, 
    Success
}

状态条件.cs

[ContentProperty(\"Content\")]
public class StateCondition : View
{
    public object State { get; set; }
    public View Content { get; set; }
}

状态容器.cs

[ContentProperty(\"Conditions\")]
public class StateContainer : ContentView
{
    public List Conditions { get; set; } = new();

    public static readonly BindableProperty StateProperty = 
        BindableProperty.Create(nameof(State), typeof(object), typeof(StateContainer), null, BindingMode.Default, null, StateChanged);

    private static void StateChanged(BindableObject bindable, object oldValue, object newValue)
    {
        var parent = bindable as StateContainer;
        if (parent != null)
            parent.ChooseStateProperty(newValue);
    }

    public object State
    {
        get { return GetValue(StateProperty); }
        set { SetValue(StateProperty, value); }
    }

    private void ChooseStateProperty(object newValue)
    {
        if (Conditions == null && Conditions?.Count == 0) return;

        var stateCondition = Conditions
            .FirstOrDefault(condition =>
                condition.State != null &&
                condition.State.ToString().Equals(newValue.ToString()));

        if (stateCondition == null) return;

        Content = stateCondition.Content;
    }
}

主页.xaml



    

        
            
                
                
        

        
            
                
                    
                        
                            
                    
                
            
        

    


MainPage.xaml.cs

public partial class MainPage : ContentPage
{
    private States _state;
    private int[] _someData;

    public MainPage()
    {
        InitializeComponent();
        this.BindingContext = this;

        SomeData = new[] { 1, 2, 3, 4, 5 };
        State = States.Success;

        // it can be executed from outside the page
        _ = Task.Run(ExecuteSomeWorkAsync);
    }

    public States State
    {
        get => _state;
        private set
        {
            if (_state != value)
            {
                _state = value;
                OnPropertyChanged();
            }
        }
    }
    public int[] SomeData
    {
        get => _someData;
        private set
        {
            if (_someData != value)
            {
                _someData = value;
                OnPropertyChanged();
            }
        }
    }

    public async Task ExecuteSomeWorkAsync()
    {
        await Task.Delay(2000);

        State = States.Loading;

        await Task.Delay(2000);

        // generate new data for displaying
        Random rnd = new();
        var data = Enumerable.Range(0, 5).Select(n => rnd.Next(0, 5)).ToArray();

        SomeData = data;
        State = States.Success;
    }
}
  • 只要属于问题域,更多的代码通常比更少的代码要好。你检查过 MAUI GitHub repo 上的问题吗?也许有一个错误: github.com/dotnet/maui/issues
  • \"但是当状态再次改变时,ListView 不会显示,直到我滑动屏幕。\" 是的。很多情况下 ListView 和 CollectionView 在更改后无法动态更新。即使强制布局也不能解决它。我不知道这个具体案例是否被列为问题,但我假设一旦基本问题得到解决,所有类似的问题也将得到解决。如果您花时间创建一个公共 github 存储库,并将其作为问题发布在上述链接中,这可能对开发人员有所帮助。还应该有助于提高潜在问题的优先级。
  • @ToolmakerSteve,谢谢!我创建了 issue request
  • @ewerspej,谢谢。我在第三点在 this closed issue 中发现了我的问题,但它不包含此问题的解决方案。
  • \"ListView 显示不正确\" .请说 确切地 什么显示不正确。以及对应的代码行。因为 Maui 是跨平台的,所以它不能很好地操作不在显示上的视图列表,例如 List<StateCondition> Conditions; 而是阅读有关 MVVM 的信息。操纵 视图模型数据 ,其中没有 UI 元素。您将更改 viewmodel 的属性,而不是 Content = stateCondition.Content ,这将导致构建不同的 UI。它是一种不同的思维方式。

【解决方案1】:

我怀疑 Content = stateCondition.Content; 不会正确更新显示。

作为替代解决方案,定义 public class StateContainer : StackLayout ,并在每个孩子上使用 IsVisible="True"/"False" ,以控制显示的内容。所有 stateConditions 仍然是 stateContainer 的子项,但一次只显示一个。

【讨论】: