using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Muchinfo.WPF.Controls
{
///
/// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
///
/// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:Muchinfo.MTPClient.Account.Views"
///
///
/// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
/// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
/// 元素中:
///
/// xmlns:MyNamespace="clr-namespace:Muchinfo.MTPClient.Account.Views;assembly=Muchinfo.MTPClient.Account.Views"
///
/// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
/// 并重新生成以避免编译错误:
///
/// 在解决方案资源管理器中右击目标项目,然后依次单击
/// “添加引用”->“项目”->[浏览查找并选择此项目]
///
///
/// 步骤 2)
/// 继续操作并在 XAML 文件中使用控件。
///
///
///
///
// [TemplatePart(Name = "XscrollViewer", Type = typeof(ScrollViewer))]
[TemplatePart(Name = "PART_HorizontalScrollBar", Type = typeof(ScrollBar))]
[TemplatePart(Name = "PART_SelectedContentHost", Type = typeof(ContentPresenter))]
[TemplatePart(Name = "Part_TabViewer", Type = typeof(ScrollViewer))]
public class OrderTabControl : TabControl
{
static OrderTabControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(OrderTabControl), new FrameworkPropertyMetadata(typeof(OrderTabControl)));
}
public OrderTabControl()
{
this.LayoutUpdated += OrderTabControl_LayoutUpdated;
}
void OrderTabControl_LayoutUpdated(object sender, EventArgs e)
{
// SetScrollBar();
}
private ScrollViewer scrollViewer = null;
private ScrollBar scrollBar = null;
private ContentPresenter presenter = null;
private bool _isSelectedChange = false;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// scrollViewer = this.GetTemplateChild("XscrollViewer") as ScrollViewer;
scrollBar = this.GetTemplateChild("PART_HorizontalScrollBar") as ScrollBar;
scrollViewer = this.GetTemplateChild("Part_TabViewer") as ScrollViewer;
if (scrollBar != null)
{
scrollBar.ValueChanged+=scrollBar_ValueChanged;
}
}
///
/// 横向滚动条的值
///
public double HSValue
{
get { return (double)GetValue(HSValueProperty); }
set { SetValue(HSValueProperty, value); }
}
// Using a DependencyProperty as the backing store for HSValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HSValueProperty =
DependencyProperty.Register("HSValue", typeof(double), typeof(OrderTabControl), new PropertyMetadata(0d,HSValueChangecalback));
///
/// 横向滚动条
///
public double ViewportWidth
{
get { return (double)GetValue(ViewportWidthProperty); }
set { SetValue(ViewportWidthProperty, value); }
}
// Using a DependencyProperty as the backing store for ViewportWidth. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ViewportWidthProperty =
DependencyProperty.Register("ViewportWidth", typeof(double), typeof(OrderTabControl), new PropertyMetadata(0d));
public double ScrollableWidth
{
get { return (double)GetValue(ScrollableWidthProperty); }
set { SetValue(ScrollableWidthProperty, value); }
}
// Using a DependencyProperty as the backing store for ScrollableWidth. This enables animation, styling, binding, etc...
public static readonly DependencyProperty ScrollableWidthProperty =
DependencyProperty.Register("ScrollableWidth", typeof(double), typeof(OrderTabControl), new PropertyMetadata(0d));
private static void HSValueChangecalback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var oTabControl = d as OrderTabControl;
if (oTabControl != null && oTabControl.scrollViewer!=null)
{
oTabControl.scrollViewer.ScrollToHorizontalOffset((double)e.NewValue);
}
}
private void scrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
{
if (scrollViewer != null)
{
scrollViewer.ScrollToHorizontalOffset((double)e.NewValue);
}
}
protected override void OnRenderSizeChanged(SizeChangedInfo info)
{
base.OnRenderSizeChanged(info);
//SetScrollBar();
}
///
/// 设置滚动条
///
private void SetScrollBar()
{
var uielement = this.SelectedContent as UIElement;
if (uielement != null)
{
scrollViewer = FindVisualChild(uielement);
}
if (scrollViewer != null && scrollBar != null)
{
//scrollBar.Value = scrollViewer.HorizontalOffset;
//scrollBar.Maximum = scrollViewer.ScrollableWidth;
//scrollBar.ViewportSize = scrollViewer.ViewportWidth;
ViewportWidth = scrollViewer.ViewportWidth;
ScrollableWidth = scrollViewer.ScrollableWidth;
HSValue = scrollViewer.HorizontalOffset;
}
}
///
/// 从父容器中查找指定类型的控件
///
///
///
///
private T FindVisualChild(DependencyObject parent) where T : DependencyObject
{
if (parent == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var childObject = VisualTreeHelper.GetChild(parent, i);
if (childObject == null) return null;
var child = childObject as T;
if (child == null)
{
var childItem = FindVisualChild(childObject);
if (childItem != null) return childItem;
}
return child;
}
return null;
}
///
/// 查找指定类型的父容器
///
///
/// The child.
/// ``0.
private static T FindVisualParent(DependencyObject child) where T : DependencyObject
{
if (child == null) return null;
var parentObject = VisualTreeHelper.GetParent(child);
if (parentObject == null) return null;
var parent = parentObject as T;
return parent ?? FindVisualParent(parentObject);
}
}
}