【发布时间】:2019-05-03 15:35:38
【问题描述】:
我通过在堆栈视图中使用可绑定布局来创建类别的水平列表,如下图所示,所以当我单击我的一个类别时,我想更改文本颜色,但实际上绑定不会更新视图在属性更改后被解雇。
<StackLayout x:Name="CategoryStack" BindableLayout.ItemsSource="{Binding CategoryListItems,Mode=TwoWay}"
Orientation="Horizontal" Padding="5,3,0,3" BackgroundColor="Transparent">
<BindableLayout.ItemTemplate>
<DataTemplate >
<custom:PancakeView BackgroundColor="White" Grid.Row="0" Grid.Column="0" IsClippedToBounds="true" Padding="4" HeightRequest="47" CornerRadius="5">
<Grid>
<Label HorizontalTextAlignment="Center" Margin="0" VerticalOptions="Center" FontSize="Small" Text="{Binding Name}" TextColor="{Binding NameColor,Mode=TwoWay}">
</Label>
</Grid>
<custom:PancakeView.GestureRecognizers>
<TapGestureRecognizer CommandParameter="{Binding .}" Command="{Binding Path=BindingContext.CategoryTappedCmd,Source={x:Reference CategoryStack}}" NumberOfTapsRequired="1" />
</custom:PancakeView.GestureRecognizers>
</custom:PancakeView>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
下面是我的 ViewModel 代码
public class ProductsListViewModel : ViewModelBase
{
private ObservableCollection<SpicesCategory> _CategoryListItems = new ObservableCollection<SpicesCategory>();
public ObservableCollection<SpicesCategory> CategoryListItems
{
get => _CategoryListItems;
set
{
_CategoryListItems = value;
RaisePropertyChanged(() => (CategoryListItems));
}
}
public ICommand CategoryTappedCmd => new Command(CategoryTapped);
public async void CategoryTapped(object obj)
{
SpicesCategory SelectedspicesCategory = obj as SpicesCategory;
foreach (var item in CategoryListItems)
{
if(item == SelectedspicesCategory)
{
item.IsSelected = true;
item.NameColor = Color.Red;
}
else
{
item.IsSelected = false;
item.NameColor = Color.Black;
}
}
}
}
下面是我的 SpicesCategory 模型
public class SpicesCategory
{
public long Id { get; set; }
public string Name { get; set; }
public bool IsSelected { get; set; }
public Color NameColor { get; set; }
}
下面是我的 ViewModelBase 继承 ExtendedBindableObject
public class ViewModelBase : ExtendedBindableObject
{
public ViewModelBase(INavigationService navigationService)
{
}
private bool _isBusy;
public event PropertyChangedEventHandler PropertyChanged;
public bool IsBusy
{
get => _isBusy;
set
{
_isBusy = value;
RaisePropertyChanged(() =>(IsBusy));
}
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public virtual Task InitializeAsync(object data)
{
return Task.FromResult(false);
}
}
下面是我继承BindableObject的ExtendedBindableObject
public abstract class ExtendedBindableObject : BindableObject
{
public void RaisePropertyChanged<T>(Expression<Func<T>> property)
{
var name = GetMemberInfo(property).Name;
OnPropertyChanged(name);
}
private MemberInfo GetMemberInfo(Expression expression)
{
MemberExpression operand;
LambdaExpression lambdaExpression = (LambdaExpression)expression;
if (lambdaExpression.Body as UnaryExpression != null)
{
UnaryExpression body = (UnaryExpression)lambdaExpression.Body;
operand = (MemberExpression)body.Operand;
}
else
{
operand = (MemberExpression)lambdaExpression.Body;
}
return operand.Member;
}
}
【问题讨论】:
-
在 SpicesCategory 类上实现 INotifyPropertyChanged
-
@MaxHampton 嗨,我实际上正在使用 RaisePropertyChanged,请检查上面的代码现在是否已更新。
-
我看到您在 ViewModel 类上实现了 INotifyPropertyChanged,但您没有将文本颜色绑定到 ViewModel 上的属性,而是绑定到 SpicesCategory 上的属性。在这种情况下,您需要来自包含您要绑定的属性的类的属性更改通知。更改应该从您设置 item.Name 和 item.NameColor 的 foreach 循环触发
-
好的,我在 foreach 循环之后尝试了这个 ObservableCollection
NewCategory = new ObservableCollection ();新类别 = 类别列表项; CategoryListItems = new ObservableCollection (); CategoryListItems = 新类别;但它不起作用,问题是我的 UI 部分没有更新,我的模型正在获取更新的值 -
您只需要
SpicesCategory : BindableObject和设置器中的 RaisePropertyChanged
标签: mvvm xamarin.forms