網站首頁 編程語言 正文
效果
概述
最近有個小需求要用雙滑塊表示一個取值范圍,于是就簡單做了個用戶控件,在此記錄下.
使用矩形Rectangle表示范圍,橢圓Ellipse表示滑塊,使用Canvas控制滑塊的左右移動.
橢圓的鼠標按下事件里強制獲取鼠標事件焦點,避免移動過快或移出控件范圍時,滑塊就不跟著跑了.橢圓的鼠標抬起事件釋放強制獲取鼠標事件焦點
代碼部分
需求比較簡單,只定義了4個依賴屬性,范圍的最大值和最小值,取值的最大值和最小值.
接下來就是計算滑塊和高亮矩形的位置,計算時注意減去橢圓Ellipse控件(圓)的半徑,使圓心對準值,而不是左側對準值.
鼠標移動的時候,計算當前位置對應的值,去改變依賴屬性的值:
private void ell_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
double percentage = e.GetPosition(rect).X / rect.ActualWidth;
double value = (Maximum - Minimum) * percentage + Minimum;
if (_ellFromPressed)
{
MinValue = (int)value;
}
if (_ellToPressed)
{
MaxValue = (int)value;
}
}
}
依賴屬性的值變化,引起滑塊的位置變化和高亮滑塊寬度和位置的變化:
//最小值變化
private void MinValuePropertyChanged()
{
if (MinValue < Minimum)
{
MinValue = Minimum;
return;
}
if (MinValue > MaxValue)
{
MaxValue = MinValue;
}
//滑塊位置變化
_offsetFrom = (MinValue - Minimum) * rect.ActualWidth / (Maximum - Minimum) - 8;
Canvas.SetLeft(ellFrom, _offsetFrom);
//高亮矩形長度和位置的變化
if (_offsetTo != -1)
{
double diff = _offsetTo - _offsetFrom;
if (diff >= 0)
{
rectHighLight.Width = diff;
Canvas.SetLeft(rectHighLight, _offsetFrom);
}
}
}
//最大值變化
private void MaxValuePropertyChanged()
{
if (MaxValue > Maximum)
{
MaxValue = Maximum;
return;
}
if (MaxValue < MinValue)
{
MinValue = MaxValue;
}
//滑塊位置變化
_offsetTo = (MaxValue - Minimum) * rect.ActualWidth / (Maximum - Minimum) - 8;
Canvas.SetLeft(ellTo, _offsetTo);
//高亮矩形長度和位置的變化
if (_offsetFrom != -1)
{
double diff = _offsetTo - _offsetFrom;
if (diff >= 0)
{
rectHighLight.Width = diff;
Canvas.SetLeft(rectHighLight, _offsetFrom);
}
}
}
取值的TextBox沒有封裝在用戶控件里,是單獨的兩個TextBox跟依賴屬性雙向綁定的.注意綁定的時候觸發方式最好不要用PropertyChanged,沒有防抖效果,不然體驗不是很好.回車觸發就可以了.
前臺雙向綁定:
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <local:DoubleThumbSlider x:Name="dts" Width="500" Minimum="100" Maximum="200"></local:DoubleThumbSlider> <TextBox Name="tMin" Width="48" Text="{Binding ElementName=dts,Path=MinValue,UpdateSourceTrigger=Explicit,Mode=TwoWay}" PreviewKeyUp="tbox_PreviewKeyUp"></TextBox> <TextBlock Margin="5,0" Text="-"></TextBlock> <TextBox Name="tMax" Width="48" Text="{Binding ElementName=dts,Path=MaxValue,UpdateSourceTrigger=Explicit,Mode=TwoWay}" PreviewKeyUp="tbox_PreviewKeyUp"></TextBox> </StackPanel>
后臺回車觸發:
private void tbox_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
TextBox tbox = (TextBox)sender;
var binding = tbox.GetBindingExpression(TextBox.TextProperty);
binding.UpdateSource();
}
}
源碼下載:DoubleThumbSlider.zip?提取碼:1234
原文鏈接:https://www.cnblogs.com/tsliwei/p/16440364.html
相關推薦
- 2024-01-11 String數組轉List的三種方式
- 2022-09-15 C#中DateTime的時間加減法操作小結_C#教程
- 2022-04-12 網絡編程——Http請求方式Get與Post
- 2023-01-28 詳解如何利用C#實現漢字轉拼音功能_C#教程
- 2022-09-14 Python深入淺出分析enum枚舉類_python
- 2022-10-13 Windows命令批處理的用法詳解_DOS/BAT
- 2022-08-17 Python連接數據庫并批量插入包含日期記錄的操作_python
- 2022-11-12 基于Python制作一個匯率換算程序_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支