[C#/WPF] TextBox.Text 에 Binding된 속성이 즉시 업데이트되지 않는 경우

포커스를 잃을 때만 업데이트되는 TextBox.Text Binding

  방금 TextBox.Text에 따라 WebBrowser.NavigateToString()을 호출하려 하는 중, 괜히 Binding을 쓰고 싶어서 TextBox.Text에 Binding Html을 걸어놓고 디버그를 해보니 텍스트가 입력될 때가 아니라, 텍스트박스의 포커스를 잃을 때 Html 프로퍼티가 업데이트되는 현상을 발견했습니다.

  제 목적은 실시간으로 WebBrowser에 TextBox에 입력된 HTML을 렌더링하는 작업이기 때문에 매우 곤란한 상황이죠.

  하지만 언제나 그렇듯, 답은 매우 간단했습니다.

Binding.UpdateSourceTrigger 프로퍼티

  Binding 클래스에는 UpdateSourceTrigger라는 프로퍼티가 있습니다. 이름에서 알 수 있듯, 언제 원본의 값을 업데이트할지 결정하는 녀석이죠. 기본값은 Default이며 Default는 Binding이 적용될 DependencyProperty를 만들 때 설정한 기본값으로 동작합니다.

  Binding.UpdateSourceTrigger 프로퍼티에 들어갈 수 있는 값은 UpdateSourceTrigger 열거형의 값들인데요, 아래와 같습니다.


  public enum UpdateSourceTrigger
  {
    Default,
    PropertyChanged,
    LostFocus,
    Explicit,
  }

  Default는 위에서 말씀드렸듯, DependencyProperty를 만들 때 설정한 기본값입니다.
  PropertyChanged는 해당 DependencyProperty에 변경이 생길 때 원본을 업데이트합니다.
  LostFocus는 DependencyProperty를 지닌 컨트롤이 포커스를 잃을 때 원본을 업데이트합니다.
  Explicit은 원본을 업데이트하기 위해 BindingExpression.UpdateSource()를 호출해야합니다. 이 때, Mode가 TwoWay 또는 OneWayToSource여야 합니다.

  자, 이제 원인을 대강 알 것 같지 않나요? UpdateSourceTrigger.LostFocus의 설명을 보면 지금 상황과 딱 들어맞죠. 컨트롤이 포커스를 잃을 때 원본을 업데이트한다.

  검증을 위해 TextBox.TextProperty 선언을 보면 아래와 같이 되어 있습니다.


public static readonly DependencyProperty TextProperty = DependencyProperty.Register(nameof (Text), typeof (string), typeof (TextBox), (PropertyMetadata) new FrameworkPropertyMetadata((object) string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, new PropertyChangedCallback(TextBox.OnTextPropertyChanged), new CoerceValueCallback(TextBox.CoerceText), true, UpdateSourceTrigger.LostFocus));


  UpdateSourceTrigger 인자의 매개 변수로 UpdateSourceTrigger.LostFocus가 들어가 있는 것이 보이시죠? 평상시와 같이 Text="{Binding Html}"로 바인드하면 당연히 UpdateSourceTrigger는 기본값인 LostFocus가 됩니다. 그래서 실시간으로 업데이트되지 않고 포커스를 잃을 때 업데이트된 것입니다.

  원인을 알았으니 해결을 해야겠죠? 어렵지 않습니다. 콤마 한개와, 약간의 타이핑만 있으면 됩니다.

  Text="{Binding Html, UpdateSourceTrigger=PropertyChanged}"

  이제 텍스트를 입력할 때마다 원본이 업데이트됩니다. 참 쉽죠?

댓글

이 블로그의 인기 게시물

C# 남아도는 메모리에도 불구하고 OutOfMemoryException이 발생한다면?

USB를 뒤는 괜찮은데 앞에 꽂으면 인식이 힘들다?

MySQL 데이터 타입과 Java 데이터 타입 비교/매칭