【问题标题】:Binding value is not updating on entry control from other xaml绑定值未更新来自其他 xaml 的条目控制
【发布时间】:2019-08-18 08:37:14
【问题描述】:

我的 XAML 中有一个条目控件,我在其中设置了页面上的初始值,通过数据绑定显示。最初该值出现,但是当我从另一个视图模型更新它时,它没有在 UI 上更新。

下面是 XAML 代码和 XAML.CS

        <ListView
        x:Name="workList"
        Grid.Row="2"
        SeparatorColor="{DynamicResource AccentColor}"
        ItemsSource="{ Binding WorkItems }"                   
        Margin="5"
        CachingStrategy="RecycleElement"
        RowHeight="440"
        SeparatorVisibility="Default"
        SelectionMode="None"
        HasUnevenRows="False">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <local:LoadItemPutawayTemplate />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>


 <?xml version="1.0" encoding="UTF-8"?>
 <ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
         xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
         xmlns:d="http://xamarin.com/schemas/2014/forms/design"
         xmlns:mc="http://schemas.openxmlformats.org/markup- 
         compatibility/2006"
         mc:Ignorable="d"
         x:Class="Sanipex.LoadItemPutawayTemplate">

<Grid
    RowSpacing="0"
    Padding="0"
    Margin="0,10,0,0"
    >

    <Grid.RowDefinitions>
        <RowDefinition
            Height="*" />
    </Grid.RowDefinitions>


            <Entry
                x:Name="OverrideLoc"
                 Grid.Row="0"
                TextColor="Black"
                WidthRequest="110"
                Text="{Binding toLocation}"
                grial:EntryProperties.BorderCornerRadius="10"
                grial:EntryProperties.BorderStyle="RoundRect"
                grial:EntryProperties.BorderColor="Black"
                HorizontalOptions="StartAndExpand"
                VerticalOptions="Center"
                Focused="OverrideLoc_Focused"
                TextChanged="OverrideLoc_TextChanged"
                grial:EntryProperties.HorizontalPadding="5"
                FontAttributes="Bold"
                PlaceholderColor="Black"
                FontSize="20"/>


    </Grid>

public partial class ItemPutAway : ContentPage
{
    private static ItemPutAwayViewModel obj;
    public ItemPutAway()
    {
        InitializeComponent();


        obj = new ItemPutAwayViewModel();
        BindingContext = obj;
    }

    public static ItemPutAwayViewModel itemPutAwayViewModel
    {
        get
        {
            return obj;
        }
    }

    protected override async void OnAppearing()
    {
        obj.LoadData();
    }
}

下面是我的第一个视图模型代码

public class ItemPutAwayViewModel : INotifyPropertyChanged
{
  private IList<WorkItem> workItems;
  public event PropertyChangedEventHandler PropertyChanged;
  public string ltoLocation;

   public string toLocation
    {
        get => ltoLocation;
        set
        {
            ltoLocation = value;
            OnPropertyChanged(nameof(toLocation));
        }
    }

    public IList<WorkItem> WorkItems
    {
        get => workItems;
        set
        {
            workItems = value;
            OnPropertyChanged(nameof(WorkItems));
        }
    }

    public void LoadData()
    {
        WorkItems = App.dataManager.GetItemPutAwayWorks();
    }

    public void setLocation(string _location)
    {
        toLocation = _location;
    }

     protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

下面是我尝试将 toLocation 绑定值更新为与另一个 XAML 页面不同的值的代码,如下所示:

public partial class AvailableLocationsPopUp : PopupPage
{
    private static AvailableLocationViewModel obj;


    public AvailableLocationsPopUp(WorkItem _workItem)
    {
        InitializeComponent();


        obj = new AvailableLocationViewModel(gWorkItem.itemid);
        BindingContext = obj;
    }

    private void OnClose(object sender, EventArgs e)
    {
        PopupNavigation.Instance.PopAsync();
    }

    private void ListView_ItemTapped(object sender, ItemTappedEventArgs e)
    {
        Location content = e.Item as Location;

        ItemPutAway.itemPutAwayViewModel.setLocation("ABC-XYZ");

        PopupNavigation.Instance.PopAsync();

    }
}

【问题讨论】:

  • 你为什么在同一个页面中有 2 个视图模型?请提供完整的样本,否则难以分析问题
  • 对不起,实际上我正在从另一个 Xaml 页面更新绑定值,我已经更新了代码
  • 再一次,您如何在 PopupPage 中访问 ItemPutAway?
  • ItemPutAway 是公共 XAML 页面,我在那里创建了静态方法来获取 ItemPutAwayViewModel 对象
  • 调用 setLocation() 更新项目的后备存储而不调用 PropertyChanged。如果您希望 UI 更新,这正是错误的做法。改用属性设置器

标签: xaml xamarin xamarin.forms data-binding xamarin-binding


【解决方案1】:

正如我在讨论中提到的,您还必须实现类WorkItemINotifyPropertyChanged 接口。

在 ItemPutAwayViewModel 中实现 INotifyPropertyChanged 只会有助于 WorkItems 中的更改(例如添加或删除一个 WorkItem),而不是 WorkItem 中的更改。

所以,代码应该是:

public class WorkItem : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private string _toLocation; 

    public string toLocation 
    { 
    get => _toLocation; 
    set 
        { 
          _toLocation = value; 
          NotifyPropertyChanged(); 
        } 
    } 

    protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "") 
    { 
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 

}

【讨论】:

  • 嗨,杰克,我现在在 WorkItem 上遇到问题,我正在向 workItem 添加新项目,但 UI 直到我返回并再次出现时才会显示。你有什么想法吗?
  • 请打开一个新线程并在其中添加您的代码,然后我可以为您检查。
  • 我开了一个新的
  • 您是否在模型项目中的其他属性(例如 toLocation)中调用了 NotifyPropertyChanged?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 2011-04-12
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
相关资源
最近更新 更多