匿名、xamarinフォーラムでのクロスポストは誰も私に答えません。カスタムコントロールのパラメータバインドの順序
私はXFでリピーターのようなコントロールを探していましたが、最終的にはhttp://www.qimata.com/?p=7671という非常に単純なものです。私はいつも「なぜこれを追加しないのですか、それをなぜ追加しないのですか」を始めました。それで他のプロパティとテンプレートを追加しました。今、コントロールは非常にうまく動作しますが、私は問題があります(この点を除けば、このシナリオを処理する最良の方法ではないと思っています。
すべてのロジックはItemChangedイベントにあり、ItemSourceプロパティがバインドされたときに発生します。今、最後のプロパティを書き込まない場合、イベントが発生したときにもう一方のプロパティがまだ評価されていません。例えば、この
<local:RepeaterView ShowSeparator="false" ItemsSource="{Binding itemsource}">
は最初のケースプロパティShowSeparatorに
<local:RepeaterView ItemsSource="{Binding itemsource}" ShowSeparator="false">
の同じではない火災パラメータ初期化前ItemsChangedので、期待値を有しています。さて、パラメータの順序を気にすることは受け入れられません。どうすればこれをもっとうまく扱うことができますか?
public class RepeaterView : StackLayout
{
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create(nameof(ItemTemplate), typeof(DataTemplate), typeof(RepeaterView), default(DataTemplate));
public static readonly BindableProperty HeaderTemplateProperty = BindableProperty.Create(nameof(HeaderTemplate), typeof(DataTemplate), typeof(RepeaterView), default(DataTemplate));
public static readonly BindableProperty EmptyTextTemplateProperty = BindableProperty.Create(nameof(EmptyTextTemplate), typeof(DataTemplate), typeof(RepeaterView), default(DataTemplate));
public static readonly BindableProperty ItemsSourceProperty = BindableProperty.Create(nameof(ItemsSource), typeof(ICollection), typeof(RepeaterView), new List<object>(), BindingMode.OneWay, null, propertyChanged: (bindable, oldValue, newValue) => { ItemsChanged(bindable, (ICollection)oldValue, (ICollection)newValue); });
public static readonly BindableProperty EmptyTextProperty = BindableProperty.Create(nameof(EmptyText), typeof(string), typeof(RepeaterView), string.Empty);
public static readonly BindableProperty SelectedItemCommandProperty = BindableProperty.Create(nameof(SelectedItemCommand), typeof(ICommand), typeof(RepeaterView), default(ICommand));
public ICollection ItemsSource
{
get { return (ICollection)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public DataTemplate ItemTemplate
{
get { return (DataTemplate)GetValue(ItemTemplateProperty); }
set { SetValue(ItemTemplateProperty, value); }
}
public DataTemplate HeaderTemplate
{
get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
set { SetValue(HeaderTemplateProperty, value); }
}
public DataTemplate EmptyTextTemplate
{
get { return (DataTemplate)GetValue(EmptyTextTemplateProperty); }
set { SetValue(EmptyTextTemplateProperty, value); }
}
public string EmptyText
{
get { return (string)GetValue(EmptyTextProperty); }
set { SetValue(EmptyTextProperty, value); }
}
public ICommand SelectedItemCommand
{
get { return (ICommand)GetValue(SelectedItemCommandProperty); }
set { SetValue(SelectedItemCommandProperty, value); }
}
public bool ShowSeparator { get; set; } = true;
private static void ItemsChanged(BindableObject bindable, ICollection oldValue, ICollection newValue)
{
var repeater = (RepeaterView)bindable;
repeater.Children.Clear();
var headerTemplate = repeater.HeaderTemplate;
if (headerTemplate != null)
{
var content = headerTemplate.CreateContent();
if (!(content is View) && !(content is ViewCell))
{
//throws exception
}
var view = (content is View) ? content as View : ((ViewCell)content).View;
repeater.Children.Add(view);
repeater.Children.Add(new Divider());
}
if (newValue.Count == 0 && (repeater.EmptyTextTemplate != null || !string.IsNullOrEmpty(repeater.EmptyText)))
{
if (repeater.EmptyTextTemplate == null)
repeater.Children.Add(new Label { Text = repeater.EmptyText });
else
{
var content = repeater.EmptyTextTemplate.CreateContent();
if (!(content is View) && !(content is ViewCell))
{
//throws exception
}
var view = (content is View) ? content as View : ((ViewCell)content).View;
repeater.Children.Add(view);
}
return;
}
var dataTemplate = repeater.ItemTemplate;
foreach (object item in newValue)
{
var content = dataTemplate.CreateContent();
if (!(content is View) && !(content is ViewCell))
{
//throws exception
}
var view = (content is View) ? content as View : ((ViewCell)content).View;
if (repeater.SelectedItemCommand != null)
{
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += (sender, e) => { repeater.SelectedItemCommand?.Execute(item); };
view.GestureRecognizers.Add(tapGestureRecognizer);
}
view.BindingContext = item;
repeater.Children.Add(view);
if (repeater.ShowSeparator)
repeater.Children.Add(new Divider { Margin = new Thickness(5, 0) });
}
}
}
}
こんにちは、ありがとうございました。私はあなたの提案された解決策を試しましたが、オーバーライドされたイベント 'protected override void LayoutChildren(double x、double y、double width、double height)' ** never ** fire、 – DottorPagliaccius