.net MAUI在ListView上显示/刷新项目时出现问题

zwghvu4y  于 2023-04-13  发布在  .NET
关注(0)|答案(2)|浏览(371)

我有一个问题。当我点击“numberOfVariables”按钮时,我在listView中看不到任何字段。既不是以前输入的,也不是新添加到ObservableCollection的。我需要这个来设置list if变量。
我做错了什么?在UWP是工作exactly。
MainPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Calc.Pages.MainPage"
         xmlns:local="using:Calc.ViewModels">
<ContentPage.BindingContext>
    <local:CalculatorViewModel/>
</ContentPage.BindingContext>
    <StackLayout>
        <Entry x:Name="numberOfVariables" Placeholder="0"/>
        <Button Text="Dalej" Clicked="SetNumbersOfVariables"/>
        <StackLayout x:Name="calcLayout" IsVisible="false">
            <ListView ItemsSource="{Binding Variables}" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Background="red">
                                <Label Text="nowy"/>
                                <Entry x:Name="{Binding Name}"
                                       Placeholder="name"/>
                                <Entry x:Name="{Binding Value}"
                                        Placeholder="0" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </StackLayout>
</ContentPage>

MainPage.cs

namespace Calc.Pages;
public partial class MainPage : ContentPage
{
    internal CalculatorViewModel viewModel { get; set; }
    public MainPage()
    {
        InitializeComponent();
        viewModel = new CalculatorViewModel();
    }

    private void SetNumbersOfVariables(object sender, EventArgs e)
    {
        if (numberOfVariables.Text == null)
            return;

        _ = int.TryParse(numberOfVariables.Text.ToString(), out int nrOf);
        viewModel.SetNumberOfVariables(nrOf);
        calcLayout.IsVisible = true;
    }
}

Variable.cs

namespace Calc.Models
{
    public class Variable
    {
        public string Name { get; set; }
        public float Value { get; set; }
    }
}

CalculatorViewModel.cs

namespace Calc.ViewModels
{
    public class CalculatorViewModel 
    {
        public ObservableCollection<Variable> Variables = new()
        {
            new Variable()
            {
                Name = "x",
                Value = 1
            },
               new Variable()
            {
                Name = "y",
                Value = 2
            }
        };

        internal void SetNumberOfVariables(int nrOf)
        {
            for (int i = 0; i < nrOf; i++)
                Variables.Add(new Variable());
        }
    }
}
nwo49xxi

nwo49xxi1#

原始答案

你没有正确设置BindingContext。你不需要在XAML中设置它,所以从那里删除它并修复代码隐藏,如下所示:

XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"          
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Calc.Pages.MainPage"         
             xmlns:local="using:Calc.ViewModels">
  <StackLayout>
    <Entry x:Name="numberOfVariables" Placeholder="0"/>
    <Button Text="Dalej" Clicked="SetNumbersOfVariables"/>
    <StackLayout>
        <Entry x:Name="numberOfVariables" Placeholder="0"/>
        <Button Text="Dalej" Clicked="SetNumbersOfVariables"/>
        <StackLayout x:Name="calcLayout" IsVisible="false">
            <ListView ItemsSource="{Binding Variables}" >
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <StackLayout Background="red">
                                <Label Text="nowy"/>
                                <Entry x:Name="{Binding Name}"
                                       Placeholder="name"/>
                                <Entry x:Name="{Binding Value}"
                                        Placeholder="0" />
                            </StackLayout>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </StackLayout>
</ContentPage>

代码隐藏

在这里,您应该设置BindingContext

namespace Calc.Pages;
public partial class MainPage : ContentPage
{
    private CalculatorViewModel viewModel;
    public MainPage()
    {
        InitializeComponent();
        BindingContext = viewModel = new CalculatorViewModel();
    }

  //...
}

备注

请注意,Variables类没有实现INotifyPropertyChanged接口,这意味着您的View不会收到您绑定的值的更新。有像CommunityToolkit.Mvvm这样的库。
此外,您可能需要重新考虑如何解析输入文本:

if (string.IsNullOrWhiteSpace(numberOfVariables.Text))
{
    return;
}

if (int.TryParse(numberOfVariables.Text, out int nrOf))
{
    viewModel.SetNumberOfVariables(nrOf);
}

更新

我注意到你的Variables集合是一个字段,而不是一个属性。你需要通过至少提供一个getter来将它更改为属性,以使绑定工作:

namespace Calc.ViewModels
{
    public class CalculatorViewModel 
    {
        public ObservableCollection<Variable> Variables { get; set; } = new()
        {
            new Variable()
            {
                Name = "x",
                Value = 1
            },
               new Variable()
            {
                Name = "y",
                Value = 2
            }
        };

        // ...
    }
}
mf98qq94

mf98qq942#

我改变了我的代码,但仍然没有工作。至于值的变化,我不需要它。我在开始时添加了一些,看看它是否会工作。
我修复了它,这是工作代码:(需要先在viewmodel构造函数中设置私有ObservableCollection,并将其绑定到公共变量,但BindingContext也必须像你写的那样在构造函数上)
MainPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         x:Class="Calc.Pages.MainPage"
         xmlns:local="using:Calc.ViewModels">
<StackLayout>
    <Entry x:Name="numberOfVariables"
   Placeholder="0"/>
    <Button Text="Dalej" Clicked="SetNumbersOfVariables"/>
    <StackLayout x:Name="calcLayout" IsVisible="false">
        <ListView ItemsSource="{Binding Variables}" >
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Entry x:Name="{Binding Name}"
                                   Placeholder="name"/>
                            <Entry x:Name="{Binding Value}"
                                    Placeholder="0" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</StackLayout>

MainPage.xaml.cs

public partial class MainPage : ContentPage
{
  internal CalculatorViewModel viewModel { get; set; }

  public MainPage()
  {
    InitializeComponent();
    BindingContext = viewModel = new CalculatorViewModel();
  }

  private void SetNumbersOfVariables(object sender, EventArgs e)
  {
    if (String.IsNullOrWhiteSpace(numberOfVariables.Text))
        return;

    if(int.TryParse(numberOfVariables.Text.ToString(), out int nrOf))
        viewModel.SetNumberOfVariables(nrOf);

    calcLayout.IsVisible = true;
  }
}

CalculatorViewModel.cs

public class CalculatorViewModel 
{
    private ObservableCollection<Variable> _variables;

    public ObservableCollection<Variable> Variables { get { return _variables; } }

    public CalculatorViewModel() 
    { 
        _variables = new ObservableCollection<Variable>();
    }
    internal void SetNumberOfVariables(int nrOf)
    {
        for (int i = 0; i < nrOf; i++)
            _variables.Add(new Variable());
    }
}

我不知道为什么我没有马上做。我想这不会改变什么。
P.S.在UWP是不需要实现INotifyPropertyChanged当你在ObservableCollection上操作.我测试它,当你添加新的一个列表在MAUI是相同的工作.

相关问题