通过消息中心更新列表视图中的控件值
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;
}
}
注:
- 因为我不知道
AvailableLocationsPopUp
的密码,所以我点击按钮就发送了消息。
- 为了简化UI,我在一些地方稍微修改了UI(xaml)。
- 您可以获得完整的演示 here。
结果是:
我想使用 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;
}
}
注:
- 因为我不知道
AvailableLocationsPopUp
的密码,所以我点击按钮就发送了消息。 - 为了简化UI,我在一些地方稍微修改了UI(xaml)。
- 您可以获得完整的演示 here。
结果是: