2015-09-16 12 views
7

Xamarinフォームのカスタムビューのデータを含むページのビューモデルにデータをバインドする際に問題が発生しました。次のようにこれは、ページ内で消費されるXamarin.Formsでカスタムビューをバインドする

public partial class KeyValueView : ContentView 
{ 
    public KeyValueView() 
    { 
     InitializeComponent(); 
     this.VerticalOptions = LayoutOptions.Start; 
     this.BindingContext = this; 
    } 

    public static readonly BindableProperty ValueProperty = 
       BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string)); 

    public string Value 
    { 
     get {return (string)GetValue(ValueProperty);} 
     set {SetValue(ValueProperty, value);} 
    } 

    public static readonly BindableProperty KeyProperty = 
     BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string)); 

    public string Key 
    { 
     get {return (string)GetValue(KeyProperty);} 
     set {SetValue(KeyProperty, value);} 
    } 
} 

:背後にあるコードで

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="KeyValueView"> 
    <Grid VerticalOptions="Start"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Label x:Name="KeyLabel" Text="{Binding Key}" Grid.Column="0" HorizontalOptions="Start" /> 
     <Label x:Name="ValueLabel" Text="{Binding Value}" Grid.Column="1" HorizontalOptions="EndAndExpand" /> 
    </Grid> 
</ContentView> 

私のカスタムビューは、キーと値のペアを表すラベルのペアは非常に簡単です

<views:KeyValueView Key="Order Number" Value="{Binding document_number}" /> 

問題は、Key文字列が期待どおりに表示されるが、値文字列が表示されないことです。 私はdocument_numberプロパティでPropertyChangedイベントを強制しようとしましたが、これは役に立ちませんでした。 私も明示的にカスタムビューのキー/値のプロパティのセッター中にラベル上のTextプロパティを設定しようとしている:

public string Key 
    { 
     get {return (string)GetValue(KeyProperty);} 
     set { 
      SetValue(KeyProperty, value); 
      KeyLabel.Text = value; 
     } 
    } 

ここでも、これは助けていない、セッターのコードが実行され得るように見えることはありません(Iそれにブレークポイントを置いて、私は、そのようなページ内のプロパティに直接結合した標識としてボックスコントロールのうちを追加した場合、それは)

をヒットしていなかった、これは正しく表示されます。

<Label Text="{Binding document_number}"/> 
<views:KeyValueView Key="Order Number" Value="{Binding document_number}" /> 

は誰でもできなぜこれが起こっているのかを説明してください(またはむしろ起こっていない)?

答えて

20

カスタムコントロール内にバインディングを内部的に割り当てないでください。 BindableProperty(ValueProperty)への参照として

public partial class KeyValueView : ContentView 
{ 
    public KeyValueView() 
    { 
     InitializeComponent(); 
     this.VerticalOptions = LayoutOptions.Start; 
    } 

    public static readonly BindableProperty ValueProperty = 
     BindableProperty.Create<KeyValueView, string>(w => w.Value, default(string)); 

    public string Value 
    { 
     get {return (string)GetValue(ValueProperty);} 
     set {SetValue(ValueProperty, value);} 
    } 

    public static readonly BindableProperty KeyProperty = 
     BindableProperty.Create<KeyValueView, string>(w => w.Key, default(string)); 

    public string Key 
    { 
     get {return (string)GetValue(KeyProperty);} 
     set {SetValue(KeyProperty, value);} 
    } 
    protected override void OnPropertyChanged(string propertyName) 
    { 
     base.OnPropertyChanged(propertyName); 

     if (propertyName == ValueProperty.PropertyName) 
     { 
      ValueLabel.Text = Value; 
     } 
     if (propertyName == KeyProperty.PropertyName) 
     { 
      KeyLabel.Text = Key; 
     } 
    } 
} 

<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="KeyValueView"> 
    <Grid VerticalOptions="Start"> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition /> 
      <ColumnDefinition /> 
     </Grid.ColumnDefinitions> 

     <Label x:Name="KeyLabel" Grid.Column="0" HorizontalOptions="Start" /> 
     <Label x:Name="ValueLabel" Grid.Column="1" HorizontalOptions="EndAndExpand" /> 
    </Grid> 
</ContentView> 

トリート特性(例えば値。):これを使用してください。 Value setter内で何かすると、BindablePropertyはそれについて通知されず、BindableProperty(assign/change ValueProperty)で何かをした場合、その逆になります。 - property Value setterは呼び出されません。

PropertyChangedを処理する場合は、その(OnPropertyChanged)またはActions(BindablePropertyの作成時に追加のパラメータとして)のオーバーライドがあります。

+0

これは私が必要としていたものです。バインド可能なプロパティがたくさんあるカスタムビューでは少し面倒かもしれませんが、私がそのポイントに達するとリファクタリングを見ていきます。 – MikeW

+0

偉大な答えです。それは魅力のように働く。 –

+0

propertyChanged:BindablePropertyからスタティックに、カスタムプロパティの全体的な点が再利用され、この静的メソッドではカスタム要素は1つしか使用できませんが、あなたのソリューションは魅力的に機能します – dpineda

0

私は

public KeyValueView() 
{ 
    InitializeComponent(); 
    this.VerticalOptions = LayoutOptions.Start; 
    this.Content.BindingContext = this; 
} 

をやって、その後、あなたがカスタムビューを使用しているビューのxaml.csでこれを行うことで、この作業を取得することができました:について

public ParentView() 
{ 
    InitializeComponent(); 
    BindingContext = this; 
} 

私に問題をもたらしたEntryフィールドは、defaultBindingModeパラメータがTwoWayに設定されていることを確認する必要がありました。