[英]Where does Binding expression get executed in Xamarin?
我正在创建一个具有ItemsSource
属性的自定义控件:
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create("ItemsSource", typeof(IEnumerable<object>), typeof(RadioButtonsGroup), defaultBindingMode: BindingMode.TwoWay);
public IEnumerable<object> ItemsSource
{
get { return (IEnumerable<object>)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
OnItemsAdded(this, new ItemsAddedEventArgs(value));
}
}
我在属性设置器中调用OnItemsAdded
方法,以初始化控件,仅当我这样设置属性时,它才会被调用:
myCustomControl.ItemsSource = vm.MyList;
但是通过数据绑定设置它时不会被调用:
<Controls:RadioButtonsGroup ItemsSource="{Binding MyList}" x:Name="myCustomControl"/>
因此该控件不会获得列表,也不会被初始化!
我不想使用propertyChanged
委托,因为它是静态的,我需要在其中使用实例成员。
这是一个示例,您应如何实现可绑定属性,即一个集合
public class RadioButtonsGroup : View
{
public static BindableProperty ItemsSourceProperty = BindableProperty.Create(
propertyName: nameof(ItemsSource),
returnType: typeof(IEnumerable),
declaringType: typeof(RadioButtonsGroup),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: OnItemsSourceChanged
);
public IEnumerable ItemsSource
{
get => (IEnumerable)GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty,value);
}
// gets called from BindableProperty
// whenever you assign a new value to ItemsSource property
private static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var @this = bindable as RadioButtonsGroup;
// unsubscribe from the old value
var oldNPC = oldValue as INotifyPropertyChanged;
if (oldNPC != null)
{
oldNPC.PropertyChanged -= @this.OnItemsSourcePropertyChanged;
}
var oldNCC = oldValue as INotifyCollectionChanged;
if (oldNCC != null)
{
oldNCC.CollectionChanged -= @this.OnItemsSourceCollectionChanged;
}
// subscribe to the new value
var newNPC = newValue as INotifyPropertyChanged;
if (newNPC != null)
{
newNPC.PropertyChanged += @this.OnItemsSourcePropertyChanged;
}
var newNCC = newValue as INotifyCollectionChanged;
if (newNCC != null)
{
newNCC.CollectionChanged += @this.OnItemsSourceCollectionChanged;
}
// inform the instance to do something
@this.RebuildOnItemsSource();
}
private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
// handle the collection changes
throw new NotImplementedException();
}
private void OnItemsSourcePropertyChanged(object sender, PropertyChangedEventArgs e)
{
// handle the property changes
throw new NotImplementedException();
}
private void RebuildOnItemsSource()
{
if (ItemsSource == null)
{
// clear out all
}
else
{
// complete creation of all subviews
}
}
}
您需要通知绑定MyList
属性已更改。 如果你有MyList
在页面(的代码隐藏属性xaml.cs
),它是这样的:
public class Detail : Page, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private List<int> _myList;
public List<int> MyList
{
get => _myList;
set
{
_myList = value;
NotifyPropertyChanged();
}
}
}
如您所见,您没有在setter中订阅PropertyChanged
事件,而是触发了它。 在后台, Binding
订阅此事件,并且在执行该事件时,它将更新您的自定义控件上的属性的值。
要对属性更改做出反应,您需要在BindableProperty
定义中添加另一个参数:
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create("ItemsSource", ..., propertyChanged: OnItemsSourceChanged);
static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
}
有一个很好的教程,用于构建具有可绑定属性的自定义控件: https : //mindofai.github.io/Creating-Custom-Controls-with-Bindable-Properties-in-Xamarin.Forms/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.