2010-07-01 4 views
1

저는 닷넷 데이터 바인딩 스키마와 정말 사랑에 빠져 있습니다 ...하지만 분명히 거기에 몇 가지 잡티가 있습니다. 내 클래스에 double 형 멤버 변수 Susan이 있다고 가정 해 보겠습니다. 음 속성 때문에 바인딩 외모 뭔가C# 클래스 변수의 데이터 바인딩

SusanText.DataBindings.Add("Text",datasource,"Property")

그리고 Susan 다음과 같이 텍스트 상자 SusanTextSusan을 결합 할 즉각적인 방법은없는가없는 것 같다. 그래서 나는 Susan을 공공 재산으로 만들 수 있습니다. 그러나 그것은 다소 냄새가납니다 ... 내가 계속 Susan을 숨기고 싶다면 어떻게해야합니까? (나는 내부 클래스의 private 인스턴스의 공개 속성 인 Susan을 만들 수 있다고 생각합니다.하지만 이것은 작은 double을위한 많은 작업입니다.) 그러나 더 큰 문제가 발생했습니다. 따라서 인수를 위해 이 작업을 수행하십시오.

private double Susan_; 
public double Susan{ get; set;} 
... 
SusanText.DataBindings.Add("Text",this,"Susan") 

처음에는 모든 것이 예상대로 작동하는 것 같습니다. SusanText을 변경하면 그에 따라 Susan이 변경됩니다. 그러나 Susan을 직접 변경하면 문제가 발생합니다. SusanText을 자동으로 업데이트하고 싶습니다. 따라서 Susan을 IBindable 인터페이스를 구현하는 double의 하위 클래스로 만들어야한다고 생각합니다. SusanSusanText으로 데이터 바인딩되면 해당 이벤트가 등록되고 Susan은 수정되면 다른 사용자에게 알립니다.

Susan 내가 그녀가하고 싶은 일을하는 가장 간단한 방법은 무엇입니까?

감사합니다.

답변

3

DataBinding은 값이 변경되어 다시 읽혀 져야 함을 나타내는 INotifyPropertyChanged을 발생시키기 위해 바인딩 된 클래스를 필요로합니다. 불행히도이를 구현하려면 수동 코딩 (또는 PostSharp에서 IL 코드로 필요한 코드 작성)이 필요합니다.

데이터 바인딩을 지원하기 위해 자동으로 구현 된 속성을 사용할 수 없으며 필드에 직접 바인딩 할 수 없습니다. 필요한 이벤트를 발생시킬 수있는 기회도 없습니다 (바인딩은 작동하지만 값은 변경되면 업데이트 됨).

데이터 바인딩의 또 다른 단점은 스레드를 고려하지 않는다는 것입니다. 백그라운드 스레드가 데이터 바인딩 된 값을 수정하면 데이터 바인딩은 UI를 업데이트하기 위해 크로스 스레드 호출을 시도합니다. 내가 발견 한 가장 좋은 해결 방법은 바인딩 가능한 클래스가 UI의 Synchronization Context 인스턴스를 보유하게하여 UI 스레드에서 UI 업데이트가 호출되도록합니다.

using System.ComponentModel; 

namespace MyWebGrocer.Uma.UI 
{ 
    public class BoundClass : INotifyPropertyChanged 
    { 
    private string _Name; 

    private int _Age; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public string Name 
    { 
     get 
     { 
     return _Name; 
     } 
     set 
     { 
     _Name = value; 
     OnPropertyChanged("Name"); 
     } 
    } 

    public int Age 
    { 
     get 
     { 
     return _Age; 
     } 
     set 
     { 
     _Age = value; 
     OnPropertyChanged("Age"); 
     } 
    } 

    protected void OnPropertyChanged(string propertyName) 
    { 
     var propertyChanged = PropertyChanged; 
     if (propertyChanged != null) 
     { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    } 
} 

나는 모든 것이 실망 스럽습니다. 데이터 바인딩의 이러한 단점은 어려운 방법으로 배웠습니다. 그러나 더 큰 문제로 나타 내기 전에 이러한 문제를 조기에 인식하고 보상하는 것이 좋습니다.

+0

"자동 구현 속성을 사용할 수 없습니다"잘, 당신은, 당신은 단지 설정 후 INPC을 발사 할 수 있습니다

namespace MyProject { public sealed class ViewModel : DependencyObject //handles all databinding voodoo { public string Susan { get { return (string)GetValue(SusanProperty); } set { SetValue(SusanProperty, value); } } public static readonly DependencyProperty SusanProperty = DependencyProperty.Register ("Susan", typeof(string), typeof(ViewModel)); } } 

와 XAML에서 재산. 약간 이상하게 보일 지 모르지만 의사 트랜잭션의 일부로 여러 속성을 업데이트하려는 경우와 같이 때로는 유용한 패턴입니다. – Will

+1

@ 윌,하지만 소비 클래스 (B)가 데이터 바인딩 된 클래스 (A)에 메서드를 호출하여 (A) 이벤트를 발생시키고 냄새를 풍기게 할 수 있습니다. .NET의 이벤트는 클래스 내부에서 해고 될 의도로 만들어 졌기 때문에 특별한 위임자입니다. 외부 구성 요소를 사용하여 이벤트를 트리거해야 사람들이 잊어 버릴 수 있습니다. IMO 추가 작업을 수행하고 databound 클래스를 자체 이벤트를 발생시킬 수있게 만드는 것이 좋습니다. – STW

+0

@stw 그냥 옵션, 그냥 옵션. 나는 DependencyObjects를 어떻게 든 사용하고 있습니다. 자신이 가진 바운드 속성을 쉽게 처리 할 수 ​​있습니다. – Will

0

코드가 어떻게 함께 모르는 지 알지 못해 가장 간단한 방법을 알려주지 않습니다. 코드에서 바인딩을 설정하는 경우에도 여전히 어려운 일을하는 것처럼 보입니다.

여기에 간단한 방법 :

<Window.DataContext> 
    <ViewModel xmlns="clr-namespace:MyProject" /> 
</Window.DataContext> 
<Grid> 
    <TextBox Text="{Binding Susan}" /> 
</Grid> 
+1

불행히도 나 같은 신입생을위한 부두가 너무 많습니다. 나는 아직 xaml에 대해 아무것도 모른다. 그것은 정말로 시원하고 유용하게 보입니다. 그러나 아무도 나에게 지금 그것을 배우기 위해 기꺼이 지불하지 않습니다. 그래도 고마워. – JnBrymn

+0

@John 솔직히 말해서 배우기가 힘들지 않으며 코드에서 할 때보 다 바인딩이 훨씬 쉽습니다. 또한 디자인 타임 데이터와 같은 편집기 향상 기능을 사용하면 속성 창을 사용하여 실제 데이터 컨텍스트 유형에 대한 바인딩을 만들 수 있습니다. 물은 굉장합니다. 들어 오세요. – Will

관련 문제