2016-12-07 7 views
0

私の目標は、私の見解モデルで指定されたプロパティを更新します基本的な入力コントロールを含むユーザーコントロールを作成することであるモデルのプロパティ名を表示するために2つの結合方法でユーザーコントロールを作成することはできません。 ビューモデルのプロパティ名がユーザーコントロールのプロパティとまったく同じでない限り、ビューモデルのプロパティ名にユーザーコントロールをバインドできませんでした。これは、再利用可能な2通りの再利用可能なコントロールの目的を破るものです。 私はちょうどキーコンセプトがないと思う。Xamarinフォームは

私の期待しているのは、UserEditorをページに追加してビューモデル内のさまざまな文字列プロパティにバインドできるようにすることで、UserEditorが取得/設定するプロパティは、 UserEditorの{バインディング}。

私がテストする簡単なPCLプロジェクトを作成しました。私は誰かがこれで正しい軌道に乗ることができれば非常に感謝しています。私はこれを把握するために他のすべてのリソースを使い果たしました。私はVS2015ソリューションのzipファイルを提供することはできますが、XAMのすべてのものはかなり大きい(65MB)。ここ

すべての部分である:

UserEditor.xaml:

<?xml version="1.0" encoding="UTF-8"?> 
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      x:Class="UserControl.UserEditor"> 
    <ContentView.Content> 
     <StackLayout Orientation="Vertical" Margin="0,0,0,10" > 
      <Entry x:Name="TextEntry" 
        Text="{Binding Text}" 
        HorizontalOptions="Fill"/> 
     </StackLayout> 
    </ContentView.Content> 
</ContentView> 

UserEditor.xaml.cs

using System; 
using System.Linq; 

using Xamarin.Forms; 

namespace UserControl 
{ 
    public partial class UserEditor : ContentView 
    { 
     //Bindable property for Text 
     public static readonly BindableProperty TextProperty = 
      BindableProperty.Create("Text", 
       typeof(string), 
       typeof(UserEditor), 
       string.Empty, 
       BindingMode.TwoWay, 
       null, 
       OnTextPropertyChanged, 
       null, 
       null, 
       null); 

     public static void OnTextPropertyChanged(BindableObject bindable, object oldValue, object newValue) 
     { 
      var control = bindable as UserEditor; 
      if (control == null) return; 
      control.TextEntry.Text = newValue.ToString(); 
     } 

     public UserEditor() 
     { 
      InitializeComponent(); 
     } 

     public string Text 
     { 
      get 
      { 
       return (string)GetValue(TextProperty); 
      } 
      set 
      { 
       SetValue(TextProperty, value); 
      } 
     } 
    } 
} 

MainPageViewModel.cs

using System; 
using System.ComponentModel; 
using System.Linq; 

namespace UserControl 
{ 
class MainPageViewModel : INotifyPropertyChanged 

{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public MainPageViewModel() 
    { 

    } 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); 
    } 

    string textProperyInVM = "Initial value"; 
    public string TextPropertyInVm 
    { 
     get 
     { 
      return textProperyInVM; 
     } 
     set 
     { 
      textProperyInVM = value; 
      OnPropertyChanged("TextPropertyInVm"); 

     } 
    } 
} 

}

MainPage.xamlを

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
     xmlns:local="clr-namespace:UserControl" 
     x:Class="UserControl.MainPage"> 

<!--//Page binding context is set to the view model in the page contructor.--> 
<StackLayout Orientation="Vertical"> 
<Label Text="Binding viewmodel properties to user control" /> 
    <!--//Label is bound to ViewModel field named TextPropertyInVm--> 
    <Label Text="{Binding TextPropertyInVm}" ></Label> 

    <!--//UserEditor custom control is bound to ViewModel field named TextPropertyInVm 
    //User editor will not see the view model property. 
    //User editor ALWAYS wants to work with a property named "Text" 
    //User editor neither reads nor updates the view model property specified in the Binding --> 
    <!-- 
    Text changes in the user control cause this error: 
    [0:] Binding: 'Text' property not found on 'UserControl.MainPageViewModel', target property: 'Xamarin.Forms.Entry.Text' 
    --> 
    <local:UserEditor Text="{Binding TextPropertyInVm, Mode=TwoWay}"> </local:UserEditor> 
</StackLayout> 
</ContentPage> 

MainPage.xaml.cs

using System.Text; 
using System.Threading.Tasks; 
using Xamarin.Forms; 

namespace UserControl 
{ 
public partial class MainPage : ContentPage 
{ 
    private MainPageViewModel vm; 
    public MainPage() 
    { 
     InitializeComponent(); 
     //instantiate and bind this page to a new view model. 
     vm = new MainPageViewModel(); 
     this.BindingContext = vm; 
    } 
    } 
} 

答えて

2

EDITED

二つの問題があります。MainPage.xamlを中

  1. は、あなたが持っている typo:UserEditor BindingのTextPropertyInVmではなくTextPropertyInVM。

  2. あなたはXAMLは、オブジェクトがバインドするために知っているのでUserEditorコンストラクタでTEXTENTRY上のBindingContextを設定する必要がありますに:

    公共UserEditor(){ のInitializeComponent(); TextEntry.BindingContext = this; }あなたがバインディングを使用したい

いつでも、あなたはBindingContextを、正しい範囲で適切に設定されていることを確認する必要があります。

UserEditor自体のBindingContextを、それがメインページに使われている時にバインド式を解決するために使用される(つまり、答えの元のバージョンでは間違いでした)。ただし、UserEntry.xamlのBinding式自体は、ビューモデル(または、そのページから継承したBindingContext)ではなく、UserEntryクラスのコンテキストを参照する必要があります。したがって、BindingContextはEntry要素に影響を与えるUserEntry内のスコープで設定する必要があります。

+0

しかし、これは問題を解決しません。 – TimeSlice

+0

これは問題を解決しません。バインディングコンテキストはページから継承されるため、UserEditorは正しいコンテキストを持ちます。私はユーザーエディタのコンストラクタでバインドコンテキストを設定しようとしましたが、ビューモデルではなくバインディングコンテキストのユーザーエディタを作成します。 VS2015の出力ウィンドウでエラーが発生しました: バインディング: 'UserControl.MainPageViewModel' 、ターゲットプロパティ: 'Xamarin.Forms.Entry.Text UserEditorは正しいバインディングコンテキストを持っていますが、間違ったプロパティ名を探しています。IE:TextPropertyInVmではなくText – TimeSlice

+0

更新された回答を参照してください。 – DavidS

関連する問題