我尝试在我的.NET MAUI应用程序中实现StateContainer by Patrick McCurley。当ListView第一次显示时,它工作正常。但是当状态再次改变时,ListView不显示,直到我滑动屏幕。
当我将任何视图元素(标签、按钮等)添加到包含ListView的视图时,该视图元素不会显示。但是,当我将StateContainer与任何其他视图元素一起移动到网格时,ListView会正确显示。如果网格不包含除StateContainer之外的其他元素,则ListView不会正确显示。
我不知道这里有什么问题。网格和其他视图元素对我来说不是一个解决方案,因为我的页面不应该包含任何其他元素,除了状态容器。
下面的示例重现了该问题:
我很抱歉有很多代码:)我不知道问题可能出在哪里。
States.cs
public enum States
{
Loading,
Success
}
StateCondition.cs
[ContentProperty("Content")]
public class StateCondition : View
{
public object State { get; set; }
public View Content { get; set; }
}
StateContainer.cs
[ContentProperty("Conditions")]
public class StateContainer : ContentView
{
public List<StateCondition> 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;
}
}
MainPage.xaml
<ContentPage ...>
<state:StateContainer State="{Binding State}">
<state:StateCondition State="Loading">
<StackLayout HorizontalOptions="Center" VerticalOptions="Center">
<ActivityIndicator IsRunning="True" />
<Label Text="Updating data..." />
</StackLayout>
</state:StateCondition>
<state:StateCondition State="Success">
<ListView ItemsSource="{Binding SomeData}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text="{Binding . }" />
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</state:StateCondition>
</state:StateContainer>
</ContentPage>
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;
}
}
1条答案
按热度按时间chhkpiq41#
我怀疑
Content = stateCondition.Content;
无法正确更新显示。另一种解决方案是定义
public class StateContainer : StackLayout
,并在每个子项上使用IsVisible="True"/"False"
,以控制显示的内容。所有stateConditions仍然是stateContainer的子项,但一次只能显示一个。