2012-07-09 5 views
0

데이터 소스 속성에 바인딩 된 XAML 요소가 있고 데이터 소스가 더 빠르게 변경되면 사람의 눈이 볼 수있는 것처럼 보입니다. 또한 UI가 더 빠르게 그려지고 인간의 눈이 볼 수 있다고 가정합니다. 자원 낭비. 속성 변경이 UI 다시 그리기를 트리거하는 대신 플래그를 발생시킨 다음 속성이 변경된 경우 UI 다시 그리기를 트리거하는 타이머가 좋을까요? 또는 UI가 다시 그려지는 방법을 놓치고 있습니까?XAML 바인딩 UI 업데이트

+0

그리드입니까? 또는 전체 UI? –

+2

데이터 소스가 INotifyPropertyChanged 이벤트를 발생시키는 경우 그리드가 이에 응답합니다. PropertyChanged를 자주 발생시키지 않는 타이머를 구현할 수 있습니까? 예. 500ms 후 속성이 변경되어 이벤트가 시작되지 않은 경우 이벤트를 시작합니다. – Michael

답변

0

당신 다음

private object _property; 
public object Property 
{ 
    get { return _property; } 
    set 
    { 
     if (_property != value) 
     { 
      _property = value; 
      Dispatcher.DelayInvoke("PropertyChanged_Property",(Action)(() => 
      { 
       RaisePropertyChanged("Property"); 
      }),TimeSpan.FromMilliseconds(500)); 

     } 
    } 
} 

내가 ...

하지만 그것을 확실하지 좋아 어쩌면이 같은 속성 변경 이벤트를 발생의 delyed 호출 ...

public static class DispatcherExtensions 
{ 
    private static Dictionary<string, DispatcherTimer> timers = 
     new Dictionary<string, DispatcherTimer>(); 
    private static readonly object syncRoot = new object(); 

    public static void DelayInvoke(this Dispatcher dispatcher, string namedInvocation, 
     Action action, TimeSpan delay, 
     DispatcherPriority priority = DispatcherPriority.Normal) 
    { 
     lock (syncRoot) 
     { 
      RemoveTimer(namedInvocation); 
      var timer = new DispatcherTimer(delay, priority, (s, e) => action(), dispatcher); 
      timer.Start(); 
      timers.Add(namedInvocation, timer); 
     } 
    } 


    public static void CancelNamedInvocation(this Dispatcher dispatcher, string namedInvocation) 
    { 
     lock (syncRoot) 
     { 
      RemoveTimer(namedInvocation); 
     } 
    } 

    private static void RemoveTimer(string namedInvocation) 
    { 
     if (!timers.ContainsKey(namedInvocation)) return; 
     timers[namedInvocation].Stop(); 
     timers.Remove(namedInvocation); 
    } 


} 

을 사용할 수

-1

이 경우의 전형적인 패턴을 업데이트한다

private object _property; 
    public object Property 
    { 
     get { return _property; } 
     set 
     { 
      if (_property != value) 
      { 
       _property = value; 
       RaisePropertyChanged("Property"); 
      } 
     } 
    } 

로 재산 구현되어 사용자의 값이이 경우에 UI 업데이트를 트리거 타이머

+2

Nickolay가이 패턴을 사용한다고 생각하지만 속성이 매우 빠르게 변경됩니다. – Batuu

+1

그럴 경우 해당 속성을 변경하면 UI 업데이트가 트리거되지 않으므로 UI ​​업데이트로 인한 낭비되는 리소스에 대해 염려 할 필요가 없습니다. – Dominik

-1

변경된 경우에만 바인딩의 방법 가기. UI를 유창하게 유지하려면 약 40ms의 타이머 간격을 유지하십시오. 인수없이 RaisePropertyChanged()를 호출

public class ViewModel 
{ 
    private Timer updateTimer; 
    public ViewModel() 
    { 
     updateTimer = new Timer(); 
     updateTimer.Interval = 40; 
     updateTimer.Elapsed +=new ElapsedEventHandler(updateTimer_Elapsed); 
     updateTimer.Start(); 
    } 

    private object _property; 
    public object Property 
    { 
     get { return _property; } 
     set 
     { 
      if (_property != value) 
      { 
       _property = value; 
      } 
     } 
    } 

    void updateTimer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     RaisePropertyChanged(); 
    } 
} 

모든 바인딩을 새로 고치려면 UI를 강제로. 이것을 원하지 않는다면 플래그 나 레지스트리를 사용하여 어떤 속성을 업데이트해야하는지 표시 할 수 있습니다.

+0

타이머가 도입되면 도움이되는 것보다 많은 피해가 발생하므로 해당 viewmodel 클래스가 진행 중입니다. 이벤트 처리기로 인해 루팅 될 수 있습니다. WPF가 당신을 위해 처리 할 수 ​​있다고 생각하는 것을 처리하려고 시도하지 마십시오 – Dominik

+0

나는 이것이 도움보다 많은 피해를 입었다는 것을 알지 못합니다. WPF는 항상 UI와 해당 업데이트를 처리합니다. 난 그냥 경과 타이머에 의해 속성 변경 표시를 제어하고 싶습니다. – Batuu

+0

수동으로 처리해야하는 이벤트 핸들러를 추가 했으므로 슬프다. ViewModel에서 가비지 수집을 원한다. – Dominik