2012-07-16 4 views
0

경고 - 저는 WPF와 관련하여 newb입니다. 그래서 내가 뭘 하려는지 내 ViewModel에서 문자열 속성에 바인딩 된 텍스트 상자가 있습니다. 사용자가 텍스트 상자를 지울 때, 사용자가 처음 열 때 (창을 열었을 때) 자동으로 되돌리려합니다. 기본적으로 나는 사용자가 텍스트 상자를 지우는 것을 막고있다.새 값이 비어 있으면 원래 값으로 되돌립니다.

현재 WPF는 TwoWay로 바인딩을 가지고 있으며 UpdateSourceTrigger를 PropertyChanged로 설정했습니다. 사용자가 하나의 작은 변화를 만들 때 내 ViewModel의 속성이 업데이트되기를 좋아하기 때문에 그 UpdateSourceTrigger를 유지하려고합니다. 그렇게하면 사용자가 무언가를 할 때 (예 : 사용자가 무언가를 변경했기 때문에 내 저장 버튼을 업데이트) 다른 UI 물건을 할 수 있습니다.

내 뷰 모델에서 내 재산은 내가 원래 값을 사용하려고 시도와 함께, 현재 다음과 같습니다

가 :

public string SourceName 
{ 
    get { return this.sourceName; } 
    set 
    { 
     if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase)) 
     { 
      if (!string.IsNullOrWhiteSpace(value)) 
       this.sourceName = value; 
      else 
       this.sourceName = this.configuredSource.Name; 

      RaisePropertyChanged("SourceName"); 
     } 
    } 
} 

오전 데 문제가 내가보기 내를 무시 생각입니다 때문에의 'RaisePropertyChanged' UpdateSourceTrigger 설정했습니다. 방아쇠를 꺼내면이 방법이 효과가 있지만 컨트롤을 UI 업데이트로 가져 가야합니다. 따라서 내가 할 수만 있다면 방아쇠를 계속 지키고 싶습니다.

사용자가 텍스트 상자를 지우면 누구나 원래 값으로 되돌릴 수 있습니까?

+0

당신이 관련 XAML을 게시 할 수 있습니다 : 여기

public RelayCommand SourceNameLostFocusCommand { get { return new RelayCommand(() => { if (string.IsNullOrWhiteSpace(this.SourceName)) this.SourceName = this.configuredSource.Title; }); } } 

은 RelayCommand 잃을 초점 화재 갈 수있는 내 XAML의 조각인가? – CodingGorilla

답변

0

문제는 UpdateSourceTrigger이 아니므로 WPF와 관련하여 귀하의 속성에 전달하는 값은 해당 값이됩니다. 재귀 사이클을 피하기 위해 발생시킨 속성 변경 이벤트는 무시됩니다.

당신은 다음과 같이 별도의 메시지에 이벤트를 발생해야

public string SourceName 
{ 
    get { return this.sourceName; } 
    set 
    { 
     if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase)) 
     { 
      if (!string.IsNullOrWhiteSpace(value)) 
      { 
       this.sourceName = value; 
       RaisePropertyChanged("SourceName"); 
      } 
      else 
      { 
       this.sourceName = this.configuredSource.Name; 
       this.dispatcherService.BeginInvoke(() => this.RaisePropertyChanged("SourceName")); 
      } 
     } 
    } 
} 

이 의사 코드의 종류 당신의 VM에서 Dispatcher에 접근하는 표준 방법이 없기 때문에 (하지 않는 한 MVVM 프레임 워크는 하나를 제공합니다.) 나는 보통 위와 같이 동 기적으로 그리고 비동기 적으로 호출 할 수있는 좋은 인터페이스를 가진 서비스로 포장한다.

어쨌든 요점은 WPF가 별도의 메시지에 있기 때문에 이번에 이벤트를 가져올 것이라는 점입니다. 따라서 UI에는 변경 사항이 반영됩니다.

+0

내가 발송자에게 접속할 수 있는지 알 겠지만 나는 할 수 없다고 생각합니다. – Travyguy9

+0

운영자에게 액세스 할 수 없습니다. – Travyguy9

+0

@ Travyguy9 : 무엇을 시도 했습니까? 'Dispatcher.CurrentDispatcher'를 통해 언제든지 디스패처에 접근 할 수 있습니다. 나는 그것을 서비스에서 감싸는 경향이있다. –

0

나는 그것을 작동시켰다. 해결책은 나의 재산을 '덤벨'로 만들고 그것을 공허하게하는 것이 었습니다.

public string SourceName 
{ 
    get { return this.sourceName; } 
    set 
    { 
     if (!this.sourceName.Equals(value, StringComparison.OrdinalIgnoreCase)) 
     { 
      this.sourceName = value; 
      RaisePropertyChanged("SourceName"); 
     } 
    } 
} 

그 때 나는 포커스가 텍스트 상자에 손실 될 때마다 해고 것 RelayCommand (MVVM 빛을) 할 것입니다.

xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4" 
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 

<TextBox Text="{Binding Path=SourceName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="LostFocus"> 
     <cmd:EventToCommand Command="{Binding SourceNameLostFocusCommand, Mode=OneWay}" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</TextBox> 
+0

이것은 내 제안이하는 것과 같은 효과를 달성하지만 훨씬 더 낙관적입니다. 즉, 속성이 별도의 발송자 메시지로 변경됩니다.그러나 이제는 구현을 복잡하게하고 뷰를 종속적으로 만듭니다. –

+0

디스패처에 대한 액세스 권한이 없으면 할 수있는 일이 많지 않습니다. – Travyguy9

+0

* * *는 운영자에게 액세스 권한이 있습니다. 내 대답과 내 대답을 다시 읽으십시오. –

관련 문제