2014-11-10 3 views
2

Xamarin Forms 프레임 워크를 사용하여 모바일 응용 프로그램을 개발 중입니다 (지금은 Android 만 타겟팅). 우리는 MVVMLight 툴킷을 사용하여 MVVM 패턴을 활용하는 애플리케이션을 구성했습니다. 데이터 관리를 위해 BreezeSharp를 사용하고 있습니다 (이미 웹 클라이언트 용 Breeze 친숙한 서버가 구현되어 있으므로).Xamarin Forms Entry와 BreezeSharp 엔터티 속성 바인딩

우리가 다루고있는 문제는 Breeze 엔터티의 속성에 바인딩 된 Xamarin Forms Entry 컨트롤을 입력 할 때의 응용 프로그램 충돌입니다. XAML 뷰

입력 제어 :

<Entry Text="{Binding SelectedCustomerAddress.AddressLine1}" /> 

는 뷰 모델 (집합() MVVMLight ViewModelBase 내지) 부동산 : 브리즈 CLR 타입

public CustomerAddress SelectedCustomerAddress 
{ 
    get { return this.selectedCustomerAddress; } 
    set { this.Set(() => this.SelectedCustomerAddress, ref this.selectedCustomerAddress, value);} 
} 

특성 :

public string AddressLine1 
{ 
    get { return this.GetValue<string>(); } 
    set { this.SetValue(value); } 
} 

입력 필드에 몇 개의 문자 만 입력하면 응용 프로그램이 스택 추적과 충돌합니다 :

11-10 11:51:02.896 F/  (4924): * Assertion at /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/mono/mono/metadata/sgen-stw.c:68, condition `info->stack_start >= info->stack_start_limit && info->stack_start < info->stack_end' not met 
11-10 11:51:02.900 E/mono-rt (4924): Stacktrace: 
11-10 11:51:02.900 E/mono-rt (4924): 
11-10 11:51:02.904 E/mono-rt (4924): at <unknown> <0xffffffff> 
11-10 11:51:02.908 E/mono-rt (4924): at (wrapper managed-to-native) object.MemberwiseClone (object) <IL 0x0002d, 0xffffffff> 
11-10 11:51:02.912 E/mono-rt (4924): at System.Delegate.Clone() <IL 0x00001, 0x00027> 
11-10 11:51:02.916 E/mono-rt (4924): at System.MulticastDelegate.CombineImpl (System.Delegate) <IL 0x000be, 0x0037c> 
11-10 11:51:02.916 E/mono-rt (4924): at System.Delegate.Combine (System.Delegate,System.Delegate) <IL 0x00062, 0x001f8> 
11-10 11:51:02.920 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.add_EntityPropertyChanged (System.ComponentModel.PropertyChangedEventHandler) <IL 0x0000b, 0x00057> 
11-10 11:51:02.924 E/mono-rt (4924): at Breeze.Sharp.BaseEntity.System.ComponentModel.INotifyPropertyChanged.add_PropertyChanged (System.ComponentModel.PropertyChangedEventHandler) [0x00000] in c:\GitHub\breeze.sharp\Breeze.Sharp\BaseEntity.cs:74 
11-10 11:51:02.928 E/mono-rt (4924): at Xamarin.Forms.BindingExpression.ApplyCore (object,Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,bool) <IL 0x00130, 0x0077f> 
11-10 11:51:02.928 E/mono-rt (4924): at Xamarin.Forms.BindingExpression.Apply (bool) <IL 0x00041, 0x000f3> 
11-10 11:51:02.932 E/mono-rt (4924): at Xamarin.Forms.BindingExpression/BindingExpressionPart.<PropertyChanged>b__12() <IL 0x00007, 0x0002f> 
11-10 11:51:02.932 E/mono-rt (4924): at Java.Lang.Thread/RunnableImplementor.Run() [0x0000b] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:36 
11-10 11:51:02.932 E/mono-rt (4924): at Java.Lang.IRunnableInvoker.n_Run (intptr,intptr) [0x00009] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/platforms/android-18/src/generated/Java.Lang.IRunnable.cs:71 
11-10 11:51:02.932 E/mono-rt (4924): at (wrapper dynamic-method) object.39beb2b5-65b4-431f-a21a-3e626049fa1f (intptr,intptr) <IL 0x00011, 0x0001b> 
11-10 11:51:02.932 E/mono-rt (4924): at (wrapper native-to-managed) object.39beb2b5-65b4-431f-a21a-3e626049fa1f (intptr,intptr) <IL 0x00022, 0xffffffff> 
11-10 11:51:02.936 E/mono-rt (4924): at <unknown> <0xffffffff> 
11-10 11:51:02.936 E/mono-rt (4924): at (wrapper managed-to-native) object.wrapper_native_0xb60a0eb0 (intptr,intptr,intptr,Android.Runtime.JValue[]) <IL 0x00120, 0xffffffff> 
11-10 11:51:02.936 E/mono-rt (4924): at Android.Runtime.JNIEnv.CallVoidMethod (intptr,intptr,Android.Runtime.JValue[]) [0x00040] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:504 
11-10 11:51:02.940 E/mono-rt (4924): at Android.App.Activity.RunOnUiThread (Java.Lang.IRunnable) [0x0002d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/platforms/android-18/src/generated/Android.App.Activity.cs:4130 
11-10 11:51:02.940 E/mono-rt (4924): at Android.App.Activity.RunOnUiThread (System.Action) [0x00000] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/src/Android.App/Activity.cs:23 
11-10 11:51:02.940 E/mono-rt (4924): at Xamarin.Forms.Forms/AndroidPlatformServices.BeginInvokeOnMainThread (System.Action) <IL 0x0000b, 0x00053> 
11-10 11:51:02.940 E/mono-rt (4924): at Xamarin.Forms.Device.BeginInvokeOnMainThread (System.Action) <IL 0x00006, 0x00038> 
11-10 11:51:02.940 E/mono-rt (4924): at Xamarin.Forms.BindingExpression/BindingExpressionPart.PropertyChanged (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00087, 0x00313> 
11-10 11:51:02.944 E/mono-rt (4924): at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00027, 0x00042> 
11-10 11:51:02.944 E/mono-rt (4924): at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00027, 0x00042> 
11-10 11:51:02.944 E/mono-rt (4924): at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00027, 0x00042> 

..... (2500 lines) 

11-10 11:51:03.564 E/mono-rt (4924): at (wrapper delegate-invoke) <Module>.invoke_void_object_PropertyChangedEventArgs (object,System.ComponentModel.PropertyChangedEventArgs) <IL 0x00059, 0xffffffff> 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.OnPropertyChangedCore (System.ComponentModel.PropertyChangedEventArgs) [0x0000b] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:1315 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect/<>c__DisplayClass4b.<OnPropertyChanged>b__4a() [0x00000] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:1306 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.QueueEvent (System.Action) [0x0003e] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:1362 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.OnPropertyChanged (System.ComponentModel.PropertyChangedEventArgs) [0x0003f] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:1305 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.SetValueWithEvents<T> (T,object,System.Action`3<T, object, object>) [0x00042] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:563 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.SetDpValue (Breeze.Sharp.DataProperty,object) [0x00000] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:529 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.SetValue (Breeze.Sharp.StructuralProperty,object) [0x00052] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:522 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.EntityAspect.SetValue (string,object) [0x00031] in c:\GitHub\breeze.sharp\Breeze.Sharp\EntityAspect.cs:507 
11-10 11:51:03.564 E/mono-rt (4924): at Breeze.Sharp.BaseEntity.SetValue (object,string) [0x00000] in c:\GitHub\breeze.sharp\Breeze.Sharp\BaseEntity.cs:37 
11-10 11:51:03.564 E/mono-rt (4924): at Client.Common.Model.Proxy.CustomerAddress.set_AddressLine2 (string) [0x00001] in c:\Projects\Client\source\Client.Common\Model\Proxy\CustomerAddress.cs:26 
11-10 11:51:03.564 E/mono-rt (4924): at (wrapper runtime-invoke) <Module>.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <IL 0x00052, 0xffffffff> 
11-10 11:51:03.564 E/mono-rt (4924): at <unknown> <0xffffffff> 
11-10 11:51:03.564 E/mono-rt (4924): at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <IL 0x00030, 0xffffffff> 
11-10 11:51:03.564 E/mono-rt (4924): at System.Reflection.MonoMethod.Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <IL 0x0004a, 0x0016f> 
11-10 11:51:03.564 E/mono-rt (4924): at System.Reflection.MethodBase.Invoke (object,object[]) <IL 0x00006, 0x0004b> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.BindingExpression.ApplyCore (object,Xamarin.Forms.BindableObject,Xamarin.Forms.BindableProperty,bool) <IL 0x002f4, 0x00fd3> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.BindingExpression.Apply (bool) <IL 0x00041, 0x000f3> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.Binding.Apply (bool) <IL 0x00027, 0x000db> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.BindableObject.SetValueActual (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00090, 0x00295> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.BindableObject.SetValueCore (Xamarin.Forms.BindableProperty,object,bool,bool,bool) <IL 0x00213, 0x007b7> 
11-10 11:51:03.564 E/mono-rt (4924): at Xamarin.Forms.Platform.Android.EntryRenderer.Android.Text.ITextWatcher.OnTextChanged (Java.Lang.ICharSequence,int,int,int) <IL 0x00014, 0x00087> 
11-10 11:51:03.564 E/mono-rt (4924): at Android.Text.ITextWatcherInvoker.n_OnTextChanged_Ljava_lang_CharSequence_III (intptr,intptr,intptr,int,int,int) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.18-series/3b7ef0a7/source/monodroid/src/Mono.Android/platforms/android-18/src/generated/Android.Text.ITextWatcher.cs:149 
11-10 11:51:03.564 E/mono-rt (4924): at (wrapper dynamic-method) object.369fe85e-8bc0-4aec-88da-b1540ec93f9c (intptr,intptr,intptr,int,int,int) <IL 0x00029, 0x0003f> 
11-10 11:51:03.564 E/mono-rt (4924): at (wrapper native-to-managed) object.369fe85e-8bc0-4aec-88da-b1540ec93f9c (intptr,intptr,intptr,int,int,int) <IL 0x00028, 0xffffffff> 
11-10 11:51:03.564 E/mono-rt (4924): 
11-10 11:51:03.564 E/mono-rt (4924): ================================================================= 
11-10 11:51:03.564 E/mono-rt (4924): Got a SIGSEGV while executing native code. This usually indicates 
11-10 11:51:03.564 E/mono-rt (4924): a fatal error in the mono runtime or one of the native libraries 
11-10 11:51:03.564 E/mono-rt (4924): used by your application. 
11-10 11:51:03.564 E/mono-rt (4924): ================================================================= 
11-10 11:51:03.564 E/mono-rt (4924): 
11-10 11:51:03.564 F/libc (4924): Fatal signal 11 (SIGSEGV) at 0xdeadbaad (code=1), thread 4924 (r.nimbus.mobile) 
The program 'Mono' has exited with code 0 (0x0). 

많은 이벤트가 발생하여 이벤트 스택 오버플로가 발생합니다.

Breeze 이외의 속성에 바인딩 할 때 항목이 올바르게 작동합니다. 분리 된 엔티티에 바인드 될 때도 잘 작동합니다.

브리즈 EntityAspect.cs 코드로 파고 후 나는 모든이 함수에 오는 것을 발견

internal void OnPropertyChanged(PropertyChangedEventArgs pcArgs) 
    { 
     if (this.IsDetached || !this.EntityGroup.ChangeNotificationEnabled) 
     return; 
     pcArgs = pcArgs ?? EntityAspect.AllPropertiesChangedEventArgs; 
     this.QueueEvent((Action) (() => 
     { 
     this.OnPropertyChangedCore(pcArgs); 
     this.OnEntityChangedCore(EntityAction.PropertyChange, (EventArgs) pcArgs); 
     })); 
    } 

그래서 바람에 나는 장애인 모금 이벤트 사용 :

this.EntityManager.ChangeNotificationEnabled = false; 

나타나는이 해결할 수있는 문제가 우리의 입장 구속력 문제. 그러나 다른 문제에 대한 문호가 열리는 지 확신 할 수 없습니다.

이 접근의 결과는 무엇입니까?

Breeze 코드에서 사용되는 이러한 EntityPropertyChanged 및 PropertyChanged 이벤트는 해당 코드를 첨부하기 위해서만 사용합니까?

또는이 문제에 대한 다른 접근 방법이 있습니까?

UPDATE : 우리가 같은 속성에 바인딩 UI에 둘 이상의 요소가있는 경우에 우리가 한 장소에 해당 속성을 업데이트 할 경우, 변화가 다른 장소에 표시되지 않습니다 : 처벌이다.

예제 : ListView에서 요소를 선택하고 선택한 요소를 일부 입력 필드 (ListView 외부)에 바인딩합니다. 해당 입력 필드를 통해 요소를 업데이트 할 때 변경 사항은 ListView에 표시되지 않습니다 (ListView에 알림이 전달되지 않음).

Breeze PropertyChanged 메커니즘 (EntityPropertyChanged 및 ForceEntityPropertyChanged)을 사용하면이 기능이 기본적으로 작동하지만 위에서 언급 한 것처럼 응용 프로그램이 손상 될 수 있습니다.

우리는 기본 엔터티 (Breeze BaseEntity에서 상속받은 엔터티)에서 OnPropertyChanged 및 RaisePropertyChanged 메서드를 구현했습니다.이 기법은 ObservableObject의 MVVMLight 구현과 유사합니다.

이 코드는 (응용 프로그램 충돌없이) 잘 작동

: 나는 추측하고있어

this.SelectedNote.RaisePropertyChanged("IsImportant"); 

답변

0

이를 수정하는 방법이있다 : 필요할 때마다

public bool IsImportant 
{ 
    get { return this.GetValue<bool>(); } 
    set 
    { 
     this.SetValue(value); 
     this.OnPropertyChanged(); 
    } 
} 

는 또한 우리는 RaisePropertyChanged를 호출 할 수 있습니다 사용자가 모든 문자 변경 대신 텍스트 편집을 마친 후에 만 ​​시작됩니다. 그게 당신이 당신의 응용 프로그램으로 달성하고자하는 것에 충분할 것입니까? WPF/Silverlight XAML에는 바인딩에 UpdateSourceTrigger라는 속성이 있습니다.이 속성을 사용하면 변경 내용을 푸시 할 위치를 지정할 수 있습니다. Xamarin에 연락하여 동일한 속성을 갖고 있는지 확인하고 있습니다.

+0

Xamarin forms [Entry] (http://androidapi.xamarin.com/?link=T%3aXamarin.Forms.Entry%2f*)/[편집자] (http://androidapi.xamarin.com/?link) = T % 3aXamarin.Forms.Entry % 2f *) have 텍스트를 입력 한 후 (또는 요소의 초점을 맞출 때 더 정확하게) 시작된 이벤트를 완료했습니다. 이 접근법의 문제점은 양방향 바인딩을 사용하는 대신 코드 뒤에 각 입력 필드에 대한 이벤트 처리기를 작성해야한다는 것입니다. – markolazic88

0

테스트하지 않았지만 EntityManager에서 속성 알림을 사용하지 않도록 설정할 수 있으므로 필요에 따라이 속성을 토글 할 수 있습니다.