当前位置:  开发笔记 > 编程语言 > 正文

如何在WPF选项卡控件中创建梯形选项卡

如何解决《如何在WPF选项卡控件中创建梯形选项卡》经验,为你挑选了5个好方法。

如何在WPF选项卡控件中创建梯形选项卡?
我想在Google Chrome中创建看起来像标签的非长方形标签,或者在VS 2008的代码编辑器中创建标签.

它可以用WPF样式完成,还是必须用代码绘制?

互联网上是否有任何代码示例?

编辑:

有很多示例显示如何圆角或更改选项卡的颜色,但我找不到任何更改选项卡的几何图形,如以下两个示例:

VS 2008代码编辑器选项卡
VS 2008代码编辑器选项卡


Google Chrome标签页
替代文字

这两个示例中的标签不是矩形,而是梯形.



1> 小智..:

我试图在互联网上找到这个问题的一些控制模板或解决方案,但我没有找到任何"可接受的"解决方案.所以我按照自己的方式编写了这个,这是我第一次(和最后一次)尝试的例子:



    
        
        
    


    
    

    
    
    
        
        
        
        
    
    
        
        
    

    
    
    
    


    
        
            
                
            
        
        
        
    

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace TabControlTemplate
{
public partial class Window1
{
    public Window1()
    {
        InitializeComponent();
    }
}

public class ContentToMarginConverter: IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return new Thickness(0, 0, -((ContentPresenter)value).ActualHeight, 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

public class ContentToPathConverter: IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var ps = new PathSegmentCollection(4);
        ContentPresenter cp = (ContentPresenter)value;
        double h = cp.ActualHeight > 10 ? 1.4 * cp.ActualHeight : 10;
        double w = cp.ActualWidth > 10 ? 1.25 * cp.ActualWidth : 10;
        ps.Add(new LineSegment(new Point(1, 0.7 * h), true));
        ps.Add(new BezierSegment(new Point(1, 0.9 * h), new Point(0.1 * h, h), new Point(0.3 * h, h), true));
        ps.Add(new LineSegment(new Point(w, h), true));
        ps.Add(new BezierSegment(new Point(w + 0.6 * h, h), new Point(w + h, 0), new Point(w + h * 1.3, 0), true));
        return ps;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}
}

我编写的这两个转换器用于调整选项卡大小以适应其内容.实际上,我根据内容大小制作Path对象.如果您不需要具有各种宽度的选项卡,则可以使用以下修改后的副本:


屏幕:

截图

样本项目(vs2010)


@rooks:很好的例子,谢谢!它在我的运行时工作,但我在VS2010的WPF设计器中遇到了问题.设计器崩溃时出现NullReferenceException,这似乎是由XAML中的`Path.Data`元素引起的.当我注释掉这个元素时,设计师是稳定的.你有什么线索可以修复这个问题吗?
@rooks:与此同时,我发现了一个修复程序,让你的例子也可以在VS2010的设计器视图中工作:在这个帖子中看到我的答案.

2> Slauma..:

注意:这只是一个很好的答案的附录.

虽然rooks的解决方案在运行时对我来说非常完美,但在VS2010 WPF设计器界面打开MainWindow时我遇到了一些麻烦:设计师抛出异常而没有显示窗口.TabControl.xaml中的T​​abItem的整个ControlTemplate也有一个蓝色的波浪线,工具提示告诉我发生了NullReferenceException.将相关代码移动到我的应用程序中时,我有相同的行为.问题发生在两台不同的机器上,所以我认为这与我的安装问题无关.

如果有人遇到相同的问题我发现了一个修复程序,以便该示例现在在运行时和设计器中工作:

第一:替换TabControl-XAML代码......


    
        
            
            
        
    
    
        
    

... ...


    
        
    

第二:在ContentToPathConverter类的Convert方法的末尾替换...

return ps;

... ...

PathFigure figure = new PathFigure(new Point(1, 0), ps, false);
PathGeometry geometry = new PathGeometry();
geometry.Figures.Add(figure);

return geometry;

我没有解释为什么它在设计师中运行稳定而不是车的原始代码.



3> realistschuc..:

我刚刚为WPF完成了类似Google Chrome的Tab Control.您可以在https://github.com/realistschuckle/wpfchrometabs找到该项目,并在博客文章中描述它

Google Chrome-Like WPF Tab Control

WPF中的ChromeTabControl和Visual Children

WPF Chrome标签功能

希望这有助于您更好地理解从头开始构建自定义选项卡控件.



4> pn...:

    
        
                
            
        
    
    
        
        
        
    



5> 小智..:

我知道这已经过时但我想建议:

在此输入图像描述

XAML:

    

    
        
            
            
        

        

            
                
                
            

            
                
                
            

            
                
            

            
                
                
                
            


        

    





    
    
    

视图模型:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Shapes;
    using System.ComponentModel;
    using System.Globalization;
    using System.Windows.Media;

    namespace TrapezoidTab
    {
        public class TabHeaderViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private string _tabHeaderText;
            private List _polygonPoints;
            private PointCollection _pointCollection;

            public TabHeaderViewModel(string tabHeaderText)
            {
                _tabHeaderText = tabHeaderText;
                TabPolygonPoints = GenPolygon();
            }

            public PointCollection TabPolygonPoints
            {
                get { return _pointCollection; }
                set
                {
                    _pointCollection = value;
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("TabPolygonPoints"));
                }
            }

            public string TabHeaderText
            {
                get { return _tabHeaderText; }
                set
                {
                    _tabHeaderText = value;
                    TabPolygonPoints = GenPolygon();
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("TabHeaderText"));
                }
            }

            private PointCollection GenPolygon()
            {
                var w = new FormattedText(_tabHeaderText, CultureInfo.GetCultureInfo("en-us"), FlowDirection.LeftToRight, new Typeface("Tahoma"), 12, Brushes.Black);
                var width = w.Width + 30;

                _polygonPoints = new List(4);
                _pointCollection = new PointCollection(4);

                _polygonPoints.Add(new Point(2, 21));
                _polygonPoints.Add(new Point(10, 2));
                _polygonPoints.Add(new Point(width, 2));
                _polygonPoints.Add(new Point(width + 8, 21));

                foreach (var point in _polygonPoints)
                    _pointCollection.Add(point);

                return _pointCollection;
            }
        }
    }

主要:

namespace TrapezoidTab
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            foreach (var obj in FruitTab.Items)
            {
                var tab = obj as TabItem;
                if (tab == null) continue;
                tab.DataContext = new TabHeaderViewModel(tab.Header.ToString());
            }
        }
    }
}

推荐阅读
赛亚兔备_393
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有