Xamarin.Forms 如何更改 UI DataTemplate 中的标签文本
Xamarin.Forms How to change UI label text inside DataTemplate
这段代码显示了几行图标和文本,看起来像一个简单的菜单。下面的代码工作正常。但有时我需要更改一个或多个标签的文本。
.xaml
<Frame HorizontalOptions="End" VerticalOptions="Start" BackgroundColor="Black" CornerRadius="5" >
<StackLayout Margin="0" Spacing="15" BindableLayout.ItemsSource="{Binding StockItemCollection}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Spacing="20">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</StackLayout.GestureRecognizers>
<Image Source="{Binding StockItemIcon}" WidthRequest="15" HeightRequest="15" BackgroundColor="Transparent"
VerticalOptions="Center" HorizontalOptions="Start"/>
<Label Text="{Binding StockItemTitle}" TextColor="White" FontSize="16" FontAttributes="Bold"
HorizontalOptions="Start" VerticalOptions="Center"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Frame>
背后的代码...
public MainPage()
{
InitializeComponent();
.
.
.
LoadStock();
this.BindingContext = this;
}
public ObservableCollection<StockItem> StockItemCollection { get; set; }
private void LoadStock()
{
StockItemCollection = new ObservableCollection<StockItem>
{
new StockItem { StockItemTitle = "ItemTitle 0", StockItemIcon = "Item0.png" },
new StockItem { StockItemTitle = "ItemTitle 1", StockItemIcon = "Item1.png" },
new StockItem { StockItemTitle = "ItemTitle 2", StockItemIcon = "Item2.png" },
new StockItem { StockItemTitle = "ItemTitle 3", StockItemIcon = "Item3.png" },
new StockItem { StockItemTitle = "ItemTitle 4", StockItemIcon = "Item4.png" },
new StockItem { StockItemTitle = "ItemTitle 5", StockItemIcon = "Item5.png" }
};
}
public class StockItem
{
public string StockItemTitle { get; set; }
public string StockItemIcon { get; set; }
}
...测试获取和设置...
Device.BeginInvokeOnMainThread(() =>
{
.
.
.
string before_StockItem = StockItemCollection[4].StockItemTitle;
// before_StockItem = "ItemTitle 4"
.
StockItemCollection[4].StockItemTitle = "Item 4 title Edited";
.
string after_StockItem = StockItemCollection[4].StockItemTitle;
// after_StockItem = "Item 4 title Edited"
// Problem: value updated here but NOT the label in the UI
});
这就是问题所在。 UI 中更新的值为 Not updated。
请任何人帮助。谢谢
This is where the problem is. The updated value is Not updated in the UI.
正如 Jason 所说,要在运行时更新视图,请让模型 class 实现 INotifyPropertyChanged
接口以触发 PropertyChanged。检查 tutorial.
试试下面的代码:
public class CustomModel : INotifyPropertyChanged
{
private string content;
public string Content
{
get
{
return content;
}
set
{
if (content != value)
{
content = value;
NotifyPropertyChanged();
}
}
}
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
这是 运行 gif:
我之前尝试过实施 INotifyPropertyChanged
,但做错了导致 PropertyChanged
没有触发。感谢 Jason 让我再次尝试并最终正确完成。
所以我想我应该在这里回答我自己的问题,我希望它也能帮助其他人。
实施INotifyPropertyChanged
通过改变这个
public class StockItem
{
public string StockItemTitle { get; set; }
public string StockItemIcon { get; set; }
}
对此...
public class StockItem : INotifyPropertyChanged
{
private string _stockItemTitle = string.Empty;
public string StockItemIcon { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string StockItemTitle
{
get
{
return this._stockItemTitle;
}
set
{
if (value != this._stockItemTitle)
{
this._stockItemTitle = value;
NotifyPropertyChanged();
}
}
}
}
这段代码显示了几行图标和文本,看起来像一个简单的菜单。下面的代码工作正常。但有时我需要更改一个或多个标签的文本。
.xaml
<Frame HorizontalOptions="End" VerticalOptions="Start" BackgroundColor="Black" CornerRadius="5" >
<StackLayout Margin="0" Spacing="15" BindableLayout.ItemsSource="{Binding StockItemCollection}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal" Spacing="20">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"/>
</StackLayout.GestureRecognizers>
<Image Source="{Binding StockItemIcon}" WidthRequest="15" HeightRequest="15" BackgroundColor="Transparent"
VerticalOptions="Center" HorizontalOptions="Start"/>
<Label Text="{Binding StockItemTitle}" TextColor="White" FontSize="16" FontAttributes="Bold"
HorizontalOptions="Start" VerticalOptions="Center"/>
</StackLayout>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</Frame>
背后的代码...
public MainPage()
{
InitializeComponent();
.
.
.
LoadStock();
this.BindingContext = this;
}
public ObservableCollection<StockItem> StockItemCollection { get; set; }
private void LoadStock()
{
StockItemCollection = new ObservableCollection<StockItem>
{
new StockItem { StockItemTitle = "ItemTitle 0", StockItemIcon = "Item0.png" },
new StockItem { StockItemTitle = "ItemTitle 1", StockItemIcon = "Item1.png" },
new StockItem { StockItemTitle = "ItemTitle 2", StockItemIcon = "Item2.png" },
new StockItem { StockItemTitle = "ItemTitle 3", StockItemIcon = "Item3.png" },
new StockItem { StockItemTitle = "ItemTitle 4", StockItemIcon = "Item4.png" },
new StockItem { StockItemTitle = "ItemTitle 5", StockItemIcon = "Item5.png" }
};
}
public class StockItem
{
public string StockItemTitle { get; set; }
public string StockItemIcon { get; set; }
}
...测试获取和设置...
Device.BeginInvokeOnMainThread(() =>
{
.
.
.
string before_StockItem = StockItemCollection[4].StockItemTitle;
// before_StockItem = "ItemTitle 4"
.
StockItemCollection[4].StockItemTitle = "Item 4 title Edited";
.
string after_StockItem = StockItemCollection[4].StockItemTitle;
// after_StockItem = "Item 4 title Edited"
// Problem: value updated here but NOT the label in the UI
});
这就是问题所在。 UI 中更新的值为 Not updated。 请任何人帮助。谢谢
This is where the problem is. The updated value is Not updated in the UI.
正如 Jason 所说,要在运行时更新视图,请让模型 class 实现 INotifyPropertyChanged
接口以触发 PropertyChanged。检查 tutorial.
试试下面的代码:
public class CustomModel : INotifyPropertyChanged
{
private string content;
public string Content
{
get
{
return content;
}
set
{
if (content != value)
{
content = value;
NotifyPropertyChanged();
}
}
}
protected virtual void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
这是 运行 gif:
我之前尝试过实施 INotifyPropertyChanged
,但做错了导致 PropertyChanged
没有触发。感谢 Jason 让我再次尝试并最终正确完成。
所以我想我应该在这里回答我自己的问题,我希望它也能帮助其他人。
实施INotifyPropertyChanged
通过改变这个
public class StockItem
{
public string StockItemTitle { get; set; }
public string StockItemIcon { get; set; }
}
对此...
public class StockItem : INotifyPropertyChanged
{
private string _stockItemTitle = string.Empty;
public string StockItemIcon { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string StockItemTitle
{
get
{
return this._stockItemTitle;
}
set
{
if (value != this._stockItemTitle)
{
this._stockItemTitle = value;
NotifyPropertyChanged();
}
}
}
}