標籤:使用 資料 問題 代碼 re c
最近在用WPF資料繫結重寫一下播放器項目時遇到的關於Slider的問題,在表單透明度調節和播放進度調節上用了Slider控制項。調節表單透明度我是 這麼想的:將表單的Opacity屬性的值與Slider的值綁定不就可以了,Opacity="{Binding ElementName=Slider,Path=Value,Mode=OneWay}",這樣根本不用處理Slider的值改變事件 (ValueChanged)。不過我要做儲存設定的功能,因此肯定要記錄Slider的值咯,於是處理一下ValueChanged事件,在裡面記錄 Slider的值到配置中,退出程式儲存配置,啟動程式讀取配置,再將儲存的值賦給Slider的Value。結果我發現我天真了,給了Value但是 Slider根本沒有任何變化,調試發現Value確實被儲存到了配置中,也就是說根本原因是儲存的值賦給Value沒有成功,到底是什麼原因呢我一直沒 弄明白。
另一方面做進度調節的時候,我發現ValueChanged根本不可行,因為播放器的播放進度每1秒賦給Slider的Value,這樣每秒就觸發一次ValueChanged事件,而我在播放進度的Slider的ValueChanged事件處理常式又寫的是調節播放進度的代碼(就是說Slider划到哪就播放媒體的哪段,做過音樂播放器的肯定會明白的),這樣很顯然就進入了一個死迴圈!!
靜下來想了想,不應該處理Slider的ValueChanged事件,而是應該當手動調節Slider的值時才去處理,也就是應該處理Slider的MouseLeftButtonUp事件,豁然開朗!!
結果我發現我又天真了,尼瑪調試一下發現當我手動拉動Slider的滑塊然後放出滑鼠時,根本不觸發MouseLeftButtonUp事件啊,百度一下說是因為Slider由RepeatButton和Thumb組成,而當你調節Slider時,實際會先出發RepeatButton的MouseLeftButtonUp,之後會將e.Handled設為true,也就是之後的Slider的MouseLeftButtonUp被忽略掉了(標記為已處理),所以你永遠進不到Slider的MouseLeftButtonUp事件處理事件中。那怎麼辦呢?WPF有個萬能的添加事件處理常式的方法:AddHandler,使用樣本:Slider1.AddHandler(Slider.MouseLeftButtonUp,new MouseButtonEventHandler(Slider1_MouseLeftButtonUp),true),第三個參數指定不論是否被標記為已處理(e.Handled=true)都要處理MouseLeftButtonUp事件,至此問題就解決了~
最後總結一下,不要在XAML中處理Slider的ValueChanged或MouseLeftButtonUp事件,正確處理Slider值改變事件的方式應該是在表單Loaded後,使用AddHandler處理Slider的MouseLeftButtonUp事件。至於一開始的疑問,又百度到了,說是Slider初始化後(給Value賦值),再處理ValueChanged事件就會出異常,這是個BUG啊!