From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点

---
 HMI.UI/ScrollLabel.cs |  143 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/HMI.UI/ScrollLabel.cs b/HMI.UI/ScrollLabel.cs
new file mode 100644
index 0000000..c8bb293
--- /dev/null
+++ b/HMI.UI/ScrollLabel.cs
@@ -0,0 +1,143 @@
+锘縰sing System;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media.Animation;
+
+namespace HMI.UI
+{
+    public class ScrollLabel : Control
+    {
+        static ScrollLabel()
+        {
+            DefaultStyleKeyProperty.OverrideMetadata(typeof(ScrollLabel), new FrameworkPropertyMetadata(typeof(ScrollLabel)));
+        }
+
+        private DoubleAnimation animation;
+
+        public override void OnApplyTemplate()
+        {
+            base.OnApplyTemplate();
+
+            // 鍦ㄦā鏉垮簲鐢ㄥ悗鍚姩鍒濆鍔ㄧ敾
+            var scrollViewer = GetTemplateChild("slv") as ScrollViewer;
+            var label = GetTemplateChild("label") as Label;
+            if (scrollViewer != null)
+            {
+                // 绛夊緟甯冨眬瀹屾垚鍚庡啀鍚姩鍔ㄧ敾
+                scrollViewer.Loaded += (s, e) =>
+                {
+                    var storyboard = new Storyboard();
+                    animation = new DoubleAnimation
+                    {
+                        From = 0,
+                        To = scrollViewer.ScrollableWidth,
+                        Duration = new Duration(TimeSpan.FromSeconds(3)),
+                        AutoReverse = true,
+                        RepeatBehavior = RepeatBehavior.Forever,
+                        BeginTime = TimeSpan.FromSeconds(0.2)
+                    };
+
+                    Storyboard.SetTarget(animation, scrollViewer);
+                    Storyboard.SetTargetProperty(animation, new PropertyPath(ScrollViewerBehavior.HorizontalOffsetProperty));
+
+                    storyboard.Children.Add(animation);
+                    scrollViewer.Resources["ScrollAnimation"] = storyboard;
+                    storyboard.Begin();
+                };
+            }
+        }
+
+        private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
+        {
+            //RefreshAnimation();
+        }
+
+        private void RefreshAnimation()
+        {
+            // 鏌ユ壘ScrollViewer骞堕噸鏂板惎鍔ㄥ姩鐢�
+            var scrollViewer = GetTemplateChild("slv") as ScrollViewer;
+
+            if (scrollViewer != null)
+            {
+                scrollViewer.Dispatcher.BeginInvoke(new Action(() =>
+                {
+                    // 鍋滄褰撳墠鍔ㄧ敾
+                    var storyboard = scrollViewer.Resources["ScrollAnimation"] as Storyboard;
+                    if (storyboard != null)
+                    {
+                        storyboard.Stop();
+                        if (animation != null)
+                        {
+                            animation.To = scrollViewer.ScrollableWidth;
+                        }
+                        storyboard.Begin();
+                    }
+
+                }), System.Windows.Threading.DispatcherPriority.Background);
+            }
+        }
+
+        public static readonly DependencyProperty ValueProperty =
+            DependencyProperty.RegisterAttached("Value", typeof(string), typeof(ScrollLabel),
+                new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnValueChanged)));
+
+        private static void OnValueChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
+        {
+            var scrollLabel = obj as ScrollLabel;
+            scrollLabel?.RefreshAnimation();
+        }
+
+        public event EventHandler<string> ValueChanged;
+
+        public string Value
+        {
+            get { return (string)GetValue(ValueProperty); }
+            set
+            {
+                SetValue(ValueProperty, value);
+            }
+        }
+    }
+
+    public static class ScrollViewerBehavior
+    {
+        public static readonly DependencyProperty HorizontalOffsetProperty =
+            DependencyProperty.RegisterAttached("HorizontalOffset", typeof(double), typeof(ScrollViewerBehavior),
+                new UIPropertyMetadata(0.0, OnHorizontalOffsetChanged));
+        public static void SetHorizontalOffset(FrameworkElement target, double value)
+        {
+            target.SetValue(HorizontalOffsetProperty, value);
+        }
+        public static double GetHorizontalOffset(FrameworkElement target)
+        {
+            return (double)target.GetValue(HorizontalOffsetProperty);
+        }
+        private static void OnHorizontalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
+        {
+            var view = target as ScrollViewer;
+            if (view != null)
+            {
+                view.ScrollToHorizontalOffset((double)e.NewValue);
+            }
+        }
+
+        public static readonly DependencyProperty VerticalOffsetProperty = DependencyProperty.RegisterAttached("VerticalOffset", typeof(double), typeof(ScrollViewerBehavior), new UIPropertyMetadata(0.0, OnVerticalOffsetChanged));
+        public static void SetVerticalOffset(FrameworkElement target, double value)
+        {
+            target.SetValue(VerticalOffsetProperty, value);
+        }
+        public static double GetVerticalOffset(FrameworkElement target)
+        {
+            return (double)target.GetValue(VerticalOffsetProperty);
+        }
+        private static void OnVerticalOffsetChanged(DependencyObject target, DependencyPropertyChangedEventArgs e)
+        {
+            var view = target as ScrollViewer;
+            if (view != null)
+            {
+                view.ScrollToVerticalOffset((double)e.NewValue);
+            }
+        }
+    }
+
+}

--
Gitblit v1.9.1