通过消息中心更新列表视图中的控件值

Updating control value in listview through messagecenter

我想使用 messageCenter 方法从另一个弹出页面更新 ListView 内的条目控件中的值。它没有按预期工作,因为它正在更新列表视图中的多个项目。

我的基本页面 (PageA) 有 ListView

       <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>

LoadItemPutAwayTemplate 是我的 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="*" />
       <RowDefinition
        Height="auto" />
      </Grid.RowDefinitions>

        <Entry
            x:Name="OverrideLoc"
             Grid.Row="0"
            TextColor="Black"
            WidthRequest="110"
            Text="{Binding toLocation}"
            HorizontalOptions="StartAndExpand"
            VerticalOptions="Center"
            FontAttributes="Bold"
            PlaceholderColor="Black"
            FontSize="20"/>

         <Button
                Grid.Row="1"
        HorizontalOptions="Center"
                x:Name="LocationBtn"
        Text="Override Loc"
                BackgroundColor="#25D366"
                TextColor="{DynamicResource AccentColor}"
                BorderColor="#25D366"
        Style="{ StaticResource CircleActionButtonFlatStyle }"
                Clicked="LocationBtn_Clicked"/>
       </Grid>

在 LocationBtn_Clicked 我正在调用弹出窗口

  private async void LocationBtn_Clicked(object sender, EventArgs e)
  {
        var AvailableLocationPopUp = new AvailableLocationsPopUp();
        await PopupNavigation.Instance.PushAsync(AvailableLocationPopUp);
  }

下面是我发送消息的弹出页面 (AvailableLocationsPopUp) 按钮单击方法

    private void PutawayBtn_Clicked(object sender, EventArgs e)
    {
      MessagingCenter.Send<AvailableLocationsPopUp, string>(this, 
     "Location", "XYZ");
    }

因为我在 LoadItemPutAwayTemplate 的 contentView 中有入口控件,所以我在其构造函数中订阅消息,如下所示以更新入口控件的值

    public LoadItemPutawayTemplate()
    {
        InitializeComponent();

        MessagingCenter.Subscribe<AvailableLocationsPopUp, string>(this, 
        "Location", async (sender, arg) =>
        {
            this.OverrideLoc.Text = arg;
        }
    }

但这是在更新 UI 上显示的所有 ListView 项目的值。我只想更新启动弹出窗口的项目的值。

当您在模板中订阅消息时,所有的ListView 项都会收到消息。 我已经创建了一个简单的演示来模拟您的应用程序,主要代码是:

LocationModel.cs

public class LocationModel: INotifyPropertyChanged
{
     string toLocation;

    public string ToLocation {
        set { SetProperty(ref toLocation, value); }
        get { return toLocation; }
    }

    bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

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

    public event PropertyChangedEventHandler PropertyChanged;
}

LoadItemPutawayTemplate.xaml.cs

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LoadItemPutawayTemplate : ContentView
{
    public LoadItemPutawayTemplate()
    {
        InitializeComponent();
    }

    private void LocationBtn_Clicked(object sender, EventArgs e)
    {
        LocationModel stringInThisCell = (LocationModel)((Button)sender).BindingContext;

        System.Diagnostics.Debug.WriteLine("send  msg  current update = " + stringInThisCell.ToLocation);

        string source = stringInThisCell.ToLocation;
        string result = "XYZ";

        string[] values = { source, result };

        MessagingCenter.Send<LoadItemPutawayTemplate, string[]>(this, "Location", values);
    }
}

LoadItemPutawayTemplate.xaml

<ContentView.Content>
    <Grid
         RowSpacing="0"
         Padding="0"
         Margin="0,2,0,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="100" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition  Width="*"/>
            <ColumnDefinition  Width="*"/>
        </Grid.ColumnDefinitions>

        <Entry
        x:Name="OverrideLoc"
        Grid.Column="0"
        TextColor="Black"
        WidthRequest="110"
        Text="{Binding ToLocation}"
        HorizontalOptions="StartAndExpand"
        VerticalOptions="Center"
        FontAttributes="Bold"
        PlaceholderColor="Black"
        FontSize="20"/>
        <Button
            Grid.Column="1"
            HorizontalOptions="Center"
            x:Name="LocationBtn"
            Text="Override Loc"
            BackgroundColor="#25D366"
            TextColor="{DynamicResource AccentColor}"
            BorderColor="#25D366"
            Clicked="LocationBtn_Clicked"/>
    </Grid>

</ContentView.Content>

MainPage.xaml.cs

 public partial class MainPage : ContentPage
{
    public List<LocationModel> WorkItems { get; set; }
    public MainPage()
    {
        InitializeComponent();

        WorkItems = new List<LocationModel>();

        WorkItems.Add(new LocationModel { ToLocation = "Tomato"});
        WorkItems.Add(new LocationModel { ToLocation = "Zucchini" });
        WorkItems.Add(new LocationModel { ToLocation = "Tomato2"});
        WorkItems.Add(new LocationModel { ToLocation = "Romaine2" });
        WorkItems.Add(new LocationModel { ToLocation = "Zucchin2"});

        MessagingCenter.Subscribe<LoadItemPutawayTemplate, string[]>(this,
         "Location", async (sender, values) =>
        {
            string source = values[0];
            string result = values[1];

            for (int i = 0; i < WorkItems.Count; i++)
            {
                LocationModel model = WorkItems[i];
                if (source.Equals(model.ToLocation)) {
                    model.ToLocation = result;
                    break;
                }
            }
        });

        workList.ItemsSource = WorkItems;     
    }
}

注:

  1. 因为我不知道AvailableLocationsPopUp的密码,所以我点击按钮就发送了消息。
  2. 为了简化UI,我在一些地方稍微修改了UI(xaml)。
  3. 您可以获得完整的演示 here

结果是: