【问题标题】:Why doesnt my image bind until I save my contentpage unless I save and reload为什么除非我保存并重新加载,否则我的图像直到我保存我的内容页面才绑定
【发布时间】:2021-01-04 06:13:04
【问题描述】:

当我单击一个按钮并推送一个新页面时,我目前正在尝试绑定一些属性。

从顶部开始,这就是我的应用程序的设置方式

public App()
{
    InitializeComponent();
    MainPage = new NavigationPage(new MainPage());
}

我有一个“MainPage”,它本质上是启动应用程序时显示的第一页。

在我的MainPage.xaml

我已将BindingContext 设置为MainViewModel

<ContentPage.BindingContext>
    <viewModels:MainViewModel/>
</ContentPage.BindingContext>

我还有一个按钮,它的Command 绑定到我的MainViewModel 中的命令

<Button Text="New Goal" 
        HeightRequest="50" WidthRequest="100" 
        TextColor="White"
        Margin="10"
        CornerRadius="4"
        Command="{Binding NewGoalCommand}">
    <Button.Background>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="#8FDF70" Offset="0.1" />
            <GradientStop Color="#1DBE95" Offset="1.0" />
        </LinearGradientBrush>
    </Button.Background>
</Button>

MainViewModel 非常简单。它有一个Command 属性,我在构造函数中对其进行了初始化

public ObservableCollection<Item> Items { get; set; } = new ObservableCollection<Item>();
public Command NewGoalCommand { get; set; }

public MainViewModel()
{
    NewGoalCommand = new Command(() => ShowNewGoalPage());
}

private async void ShowNewGoalPage()
{
    await Application.Current.MainPage.Navigation.PushAsync(new NewGoal(SelectedItem));
}

NewGoal.xaml

正如您在代码中看到的那样,它正在调用NewGoal,这是我单击按钮时显示的第二个页面,当我单击按钮时会显示此页面,这表明绑定成功。

此页面也是如此,我将 BindingContext 设置为我的另一个 ViewModel 负责它的相应视图,就像这样

<ContentPage.BindingContext>
    <viewModel:NewGoalViewModel/>
</ContentPage.BindingContext>

我还添加了将绑定到其相应属性的组件,以便当我单击“保存”时,它会将该项添加到 MainViewModel 内的集合中

<ContentPage.Content>
    <StackLayout Spacing="0">
        <Image WidthRequest="50" HeightRequest="50"
               Margin="10"
               Source="{Binding ItemModel.ImageSource}"/>

        <StackLayout Margin="20,0,20,0"
                     Spacing="0">
            <Label Text="Title"/>
            <Entry />
        </StackLayout>


        <StackLayout Margin="20,20,20,0"
                     Spacing="0">
            <Label Text="Description"/>
            <Entry />
        </StackLayout>


        <StackLayout Margin="20,20,20,0"
                     Spacing="0">
            <Label Text="Type"/>
            <Picker ItemsSource="{Binding ItemModel.Type}" />
        </StackLayout>

        <StackLayout Margin="20,20,20,0"
                     Spacing="0">
            <Label Text="Price"/>
            <Entry Keyboard="Numeric"/>
        </StackLayout>


        <Button Command="{Binding SaveCommand}"
                Text="Save"
                VerticalOptions="End">

        </Button>
    </StackLayout>
</ContentPage.Content>

这里是NewGoalViewModel

class NewGoalViewModel : MainViewModel
{
    public Item ItemModel { get; set; }
    public Command SaveCommand { get; set; }


    public NewGoalViewModel()
    {
        ItemModel = new Item();
        ItemModel.Title = "Title";
        ItemModel.Description = "Description";
        ItemModel.Type = SavingsType.Other;
        ItemModel.Price = 19.00f;
        ItemModel.ImageSource = "cash.jpg";


        SaveCommand = new Command(() => AddGoal());
    }

    private void AddGoal()
    {
        Items.Add(new Item { Title = "Rainy Day", Type = SavingsType.Other, Price = 100.00, ImageSource = "cash.jpg" });
    }
}

问题

因此,当我启动应用程序并单击第一个按钮时,它会将我带到下一页。 当我登陆该页面时,它应该在顶部显示Image。它绑定到我在构造函数ItemModel.ImageSource = "cash.jpg";中分配的属性@

但问题是它实际上并没有绑定,导致图像在我保存 NewGoal.xaml 页面并重新加载之前不显示。完成重新加载后,它会显示图像。

【问题讨论】:

  • save the NewGoal.xaml 是什么意思?我测试你的代码,它在我这边运行良好。您的 ImageSource 是否声明为属性? public string ImageSource { get; internal set; }

标签: xaml xamarin xamarin.forms mvvm


【解决方案1】:

尝试修改

    private Item itemModel { get; set; }
    public Item ItemModel 
    {
        get { return itemModel ; }
        set
        {
            itemModel = value;
            OnPropertyChanged();
        }
    } 

并将您的 ViewModel 继承到 : INotifyPropertyChanged
并添加它来实现

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        var changed = PropertyChanged;
        if (changed == null)
            return;

        changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

【讨论】:

  • 哇哦.. 我刚刚意识到我还在 NewGoals 页面的构造函数的代码隐藏中设置了绑定上下文,方法是执行 BindingContext = item; 并传入一个名为 item 的对象作为参数。删除它修复了它。我相信这是因为它将绑定上下文优先于 xaml 上下文。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
  • 1970-01-01
相关资源
最近更新 更多