HandyControl中Button图标展示多色路径

发布时间:2026/8/2 23:14:08

HandyControl中Button图标展示多色路径 多色路径需求在HandyControl中支持图标和图标文本显示图标主要是矢量路径也就是对应着svg的数据格式。而对于多图形GeometryGroup虽然能够多路径组合但是仅支持单色并不支持多色日常使用如下原始svg内容svgxmlnshttp://www.w3.org/2000/svgxmlns:xlinkhttp://www.w3.org/1999/xlinkfillnoneversion1.1width16height16viewBox0 0 16 16defsclipPathidmaster_svg0_103_3747rectx0y0width16height16rx0//clipPath/defsgclip-pathurl(#master_svg0_103_3747)pathdM10.832551042773437,1.59998178671875L2.8058843427734375,9.84051518671875C2.7448177427734377,9.90398218671875,2.7320177427734373,9.91651538671875,2.7082843427734375,9.97331528671875L2.6714843427734376,10.06851478671875L2.616551142773438,10.23118018671875L2.4133510427734377,10.86424728671875L2.0098843527734376,12.14691338671875L1.3573510647734375,14.24211338671875C1.2330844397734375,14.64291338671875,1.5976177427734375,15.01811338671875,1.9952178027734375,14.91758038671875L2.6701511427734372,14.69784638671875L5.239218042773437,13.85011338671875L5.939217542773438,13.61357938671875L6.079217442773437,13.56424738671875C6.099751042773438,13.55651238671875,6.116550942773437,13.55011238671875,6.131484042773438,13.54398038671875L6.192017542773438,13.51891438671875C6.248017742773437,13.49464738671875,6.260550942773437,13.48158038671875,6.321084042773437,13.42184638671875L14.353082342773437,5.17464708671875C14.756508342773438,4.760472786718751,14.756508342773438,4.10028838671875,14.353082342773437,3.68611358671875L12.341351342773438,1.61998176671875C11.930258342773438,1.19789707671875,11.254809342773438,1.18906152671875,10.832818042773438,1.60024842671875L10.832551042773437,1.59998178671875ZM3.6506848427734373,10.50264838671875L11.576818342773437,2.3642483867187503L13.589085342773437,4.430381786718749L5.645885442773437,12.58611438671875L5.209618542773438,12.73544738671875L3.7389519427734377,13.22344738671875L2.6826853427734374,13.57118138671875L3.3749520427734376,11.36104638671875L3.6157517427734374,10.60771468671875L3.6504187427734376,10.50238128671875L3.6506848427734373,10.50264838671875Zfill#FFFFFFfill-opacity1stylemix-blend-mode:passthrough/pathdM9.0365343134375,3.750135658203125C9.2321443534375,3.554630756203125,9.5447464034375,3.541084766203125,9.7565345734375,3.718935728203125L9.7906675334375,3.750135658203125L12.190666923437501,6.150135558203125C12.3937263234375,6.3518721582031255,12.4013290234375,6.677928958203125,12.2078933234375,6.888910558203126C12.0144577234375,7.099892358203125,11.688966723437499,7.120558758203125,11.470400823437501,6.935735658203125L11.4365339234375,6.904535558203126L9.0365343134375,4.5045356782031245C8.8281536104375,4.296238418203125,8.8281536104375,3.958432908203125,9.0365343134375,3.750135658203125Zfill#FFFFFFfill-opacity1stylemix-blend-mode:passthrough/pathdM13.599989443554687,13.333343505859375L13.599989443554687,13.866677345859374C13.599990343554687,14.161229195859375,13.361208443554688,14.400011205859375,13.066656543554688,14.400010105859375L8.266655443554688,14.400010105859375C7.9721040735546875,14.400011205859375,7.7333226203918475,14.161229195859375,7.7333221435546875,13.866677345859374L7.7333221435546875,13.333343505859375L13.599989443554687,13.333343505859375Zfill#00B386fill-opacity1stylemix-blend-mode:passthrough//g/svgGeometry转换实际转换为GeometryGroup后如下GeometryGroupx:KeyInputGeometryGeometryM10.832551042773437,1.59998178671875L2.8058843427734375,9.84051518671875C2.7448177427734377,9.90398218671875,2.7320177427734373,9.91651538671875,2.7082843427734375,9.97331528671875L2.6714843427734376,10.06851478671875L2.616551142773438,10.23118018671875L2.4133510427734377,10.86424728671875L2.0098843527734376,12.14691338671875L1.3573510647734375,14.24211338671875C1.2330844397734375,14.64291338671875,1.5976177427734375,15.01811338671875,1.9952178027734375,14.91758038671875L2.6701511427734372,14.69784638671875L5.239218042773437,13.85011338671875L5.939217542773438,13.61357938671875L6.079217442773437,13.56424738671875C6.099751042773438,13.55651238671875,6.116550942773437,13.55011238671875,6.131484042773438,13.54398038671875L6.192017542773438,13.51891438671875C6.248017742773437,13.49464738671875,6.260550942773437,13.48158038671875,6.321084042773437,13.42184638671875L14.353082342773437,5.17464708671875C14.756508342773438,4.760472786718751,14.756508342773438,4.10028838671875,14.353082342773437,3.68611358671875L12.341351342773438,1.61998176671875C11.930258342773438,1.19789707671875,11.254809342773438,1.18906152671875,10.832818042773438,1.60024842671875L10.832551042773437,1.59998178671875ZM3.6506848427734373,10.50264838671875L11.576818342773437,2.3642483867187503L13.589085342773437,4.430381786718749L5.645885442773437,12.58611438671875L5.209618542773438,12.73544738671875L3.7389519427734377,13.22344738671875L2.6826853427734374,13.57118138671875L3.3749520427734376,11.36104638671875L3.6157517427734374,10.60771468671875L3.6504187427734376,10.50238128671875L3.6506848427734373,10.50264838671875Z/GeometryGeometryM9.0365343134375,3.750135658203125C9.2321443534375,3.554630756203125,9.5447464034375,3.541084766203125,9.7565345734375,3.718935728203125L9.7906675334375,3.750135658203125L12.190666923437501,6.150135558203125C12.3937263234375,6.3518721582031255,12.4013290234375,6.677928958203125,12.2078933234375,6.888910558203126C12.0144577234375,7.099892358203125,11.688966723437499,7.120558758203125,11.470400823437501,6.935735658203125L11.4365339234375,6.904535558203126L9.0365343134375,4.5045356782031245C8.8281536104375,4.296238418203125,8.8281536104375,3.958432908203125,9.0365343134375,3.750135658203125Z/GeometryGeometryM13.599989443554687,13.333343505859375L13.599989443554687,13.866677345859374C13.599990343554687,14.161229195859375,13.361208443554688,14.400011205859375,13.066656543554688,14.400010105859375L8.266655443554688,14.400010105859375C7.9721040735546875,14.400011205859375,7.7333226203918475,14.161229195859375,7.7333221435546875,13.866677345859374L7.7333221435546875,13.333343505859375L13.599989443554687,13.333343505859375Z/Geometry/GeometryGroupXaml 页面使用在Button需要声明全局引入引入HandyControl库并引入命名空间hc:Windowx:Classblog_hc_button.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:blog_hc_buttonxmlns:hchttps://handyorg.github.io/handycontrolmc:IgnorabledTitleMainWindowHeight450Width800UniformGridButtonWidthAutoPadding12,6Height36FontSize14Content测试样例hc:IconElement.Geometry{StaticResource InputGeometry}hc:IconElement.Width24hc:IconElement.Height20/Button/UniformGrid/hc:Window运行效果如下字体色即为文本色源码细节分析查看Button样式通过查看HandyControl中ButtonBaseStyle样式代码去除无关部分不能看出按钮的字体颜色即为路径的填充色Path ... Fill{TemplateBinding Foreground}/Stylex:KeyButtonBaseStyleBasedOn{StaticResource ButtonBaseBaseStyle}TargetTypeButtonSetter PropertyTemplate Setter.Value ControlTemplate TargetTypeButton hc:SimplePanel Border Background{TemplateBinding Background}CornerRadius{Binding Path(hc:BorderElement.CornerRadius),RelativeSource{RelativeSource TemplatedParent}}/ Border BorderThickness{TemplateBinding BorderThickness}BorderBrush{TemplateBinding BorderBrush}CornerRadius{Binding Path(hc:BorderElement.CornerRadius),RelativeSource{RelativeSource TemplatedParent}} StackPanel OrientationHorizontalHorizontalAlignment{TemplateBinding HorizontalContentAlignment}VerticalAlignment{TemplateBinding VerticalContentAlignment}Margin{TemplateBinding Padding} !--路径图标-- Pathx:NamePathMainWidth{TemplateBinding hc:IconElement.Width}Height{TemplateBinding hc:IconElement.Height}Fill{TemplateBinding Foreground}SnapsToDevicePixelsTrueStretchUniformData{TemplateBinding hc:IconElement.Geometry}/ !--文本内容-- ContentPresenterx:NameContentPresenterMainRecognizesAccessKeyTrueVerticalAlignmentCenterMargin6,0,0,0SnapsToDevicePixels{TemplateBinding SnapsToDevicePixels}/ /StackPanel /Border /hc:SimplePanel /ControlTemplate /Setter.Value /Setter/Style查看DrawingBrush如果需要多色就需要将Button的Foreground与Icon的填充色进行分离进而实现两者的独立配置虽然GeometryGroup无法实现多色但是Fill本身可以支持DrawingBrush可以通过单独设置DrawingBrush实现图形填充色使用了DrawingGroup以及GeometryDrawing如果不熟悉可以查阅微软文档。DrawingBrushx:KeyInput2GeometryBrushDrawingBrush.DrawingDrawingGroupGeometryDrawingBrush{DynamicResource PrimaryTextBrush}Pen{x:Null}GeometryM10.832551042773437,1.59998178671875L2.8058843427734375,9.84051518671875C2.7448177427734377,9.90398218671875,2.7320177427734373,9.91651538671875,2.7082843427734375,9.97331528671875L2.6714843427734376,10.06851478671875L2.616551142773438,10.23118018671875L2.4133510427734377,10.86424728671875L2.0098843527734376,12.14691338671875L1.3573510647734375,14.24211338671875C1.2330844397734375,14.64291338671875,1.5976177427734375,15.01811338671875,1.9952178027734375,14.91758038671875L2.6701511427734372,14.69784638671875L5.239218042773437,13.85011338671875L5.939217542773438,13.61357938671875L6.079217442773437,13.56424738671875C6.099751042773438,13.55651238671875,6.116550942773437,13.55011238671875,6.131484042773438,13.54398038671875L6.192017542773438,13.51891438671875C6.248017742773437,13.49464738671875,6.260550942773437,13.48158038671875,6.321084042773437,13.42184638671875L14.353082342773437,5.17464708671875C14.756508342773438,4.760472786718751,14.756508342773438,4.10028838671875,14.353082342773437,3.68611358671875L12.341351342773438,1.61998176671875C11.930258342773438,1.19789707671875,11.254809342773438,1.18906152671875,10.832818042773438,1.60024842671875L10.832551042773437,1.59998178671875ZM3.6506848427734373,10.50264838671875L11.576818342773437,2.3642483867187503L13.589085342773437,4.430381786718749L5.645885442773437,12.58611438671875L5.209618542773438,12.73544738671875L3.7389519427734377,13.22344738671875L2.6826853427734374,13.57118138671875L3.3749520427734376,11.36104638671875L3.6157517427734374,10.60771468671875L3.6504187427734376,10.50238128671875L3.6506848427734373,10.50264838671875Z/GeometryDrawingBrush{DynamicResource PrimaryTextBrush}Pen{x:Null}GeometryM9.0365343134375,3.750135658203125C9.2321443534375,3.554630756203125,9.5447464034375,3.541084766203125,9.7565345734375,3.718935728203125L9.7906675334375,3.750135658203125L12.190666923437501,6.150135558203125C12.3937263234375,6.3518721582031255,12.4013290234375,6.677928958203125,12.2078933234375,6.888910558203126C12.0144577234375,7.099892358203125,11.688966723437499,7.120558758203125,11.470400823437501,6.935735658203125L11.4365339234375,6.904535558203126L9.0365343134375,4.5045356782031245C8.8281536104375,4.296238418203125,8.8281536104375,3.958432908203125,9.0365343134375,3.750135658203125Z/GeometryDrawingBrush{DynamicResource PrimaryBrush}Pen{x:Null}GeometryM13.599989443554687,13.333343505859375L13.599989443554687,13.866677345859374C13.599990343554687,14.161229195859375,13.361208443554688,14.400011205859375,13.066656543554688,14.400010105859375L8.266655443554688,14.400010105859375C7.9721040735546875,14.400011205859375,7.7333226203918475,14.161229195859375,7.7333221435546875,13.866677345859374L7.7333221435546875,13.333343505859375L13.599989443554687,13.333343505859375Z//DrawingGroup/DrawingBrush.Drawing/DrawingBrush逻辑代码调整创建附加属性那又该如何在Button控件中使用实际可以参考HandyControl原有自带的附加属性IconElement相关属性。本地构建一个IconElement类增加一个Brush类型的附加属性IconElement.Foreground。usingSystem.Windows;usingSystem.Windows.Media;namespaceblog_hc_button{publicclassIconElement{publicstaticBrushGetForeground(DependencyObjectobj){return(Brush)obj.GetValue(ForegroundProperty);}publicstaticvoidSetForeground(DependencyObjectobj,Brushvalue){obj.SetValue(ForegroundProperty,value);}publicstaticreadonlyDependencyPropertyForegroundPropertyDependencyProperty.RegisterAttached(Foreground,typeof(Brush),typeof(IconElement),newPropertyMetadata(Brushes.Transparent));}}需要重写原有ButtonBaseStyle样式添加IconElement.Foreground这个附加属性首先添加本地命名空间声明。xmlns:localclr-namespace:blog_hc_button重写Button样式进行Button样式覆写进而能够在控件使用时传入附加属性决定图标的颜色。hc:Windowx:Classblog_hc_button.MainWindowxmlnshttp://schemas.microsoft.com/winfx/2006/xaml/presentationxmlns:xhttp://schemas.microsoft.com/winfx/2006/xamlxmlns:dhttp://schemas.microsoft.com/expression/blend/2008xmlns:mchttp://schemas.openxmlformats.org/markup-compatibility/2006xmlns:localclr-namespace:blog_hc_buttonxmlns:hchttps://handyorg.github.io/handycontrolmc:IgnorabledTitleMainWindowHeight450Width800hc:Window.ResourcesStylex:KeyButtonBaseStyleXBasedOn{StaticResource ButtonBaseBaseStyle}TargetTypeButtonSetter PropertyBorderThicknessValue1/ Setter PropertyBackgroundValue{DynamicResource RegionBrush}/ Setter Propertyhc:BorderElement.CornerRadiusValue{StaticResource DefaultCornerRadius}/ !--给local:IconElement.Foreground设置一个默认颜色-- Setter Propertylocal:IconElement.ForegroundValue{DynamicResource PrimaryTextBrush}/ Setter PropertyTemplate Setter.Value ControlTemplate TargetTypeButton hc:SimplePanel Border Background{TemplateBinding Background}CornerRadius{Binding Path(hc:BorderElement.CornerRadius),RelativeSource{RelativeSource TemplatedParent}}/ Border BorderThickness{TemplateBinding BorderThickness}BorderBrush{TemplateBinding BorderBrush}CornerRadius{Binding Path(hc:BorderElement.CornerRadius),RelativeSource{RelativeSource TemplatedParent}} StackPanel OrientationHorizontalHorizontalAlignment{TemplateBinding HorizontalContentAlignment}VerticalAlignment{TemplateBinding VerticalContentAlignment}Margin{TemplateBinding Padding} !--路径图标设置local:IconElement.Foreground为Path的填充色-- Pathx:NamePathMainWidth{TemplateBinding hc:IconElement.Width}Height{TemplateBinding hc:IconElement.Height}Fill{TemplateBinding local:IconElement.Foreground}SnapsToDevicePixelsTrueStretchUniformData{TemplateBinding hc:IconElement.Geometry}/ ContentPresenterx:NameContentPresenterMainRecognizesAccessKeyTrueVerticalAlignmentCenterMargin6,0,0,0SnapsToDevicePixels{TemplateBinding SnapsToDevicePixels}/ /StackPanel /Border /hc:SimplePanel ControlTemplate.Triggers Trigger PropertyContentValue{x:Null} Setter PropertyVisibilityValueCollapsedTargetNameContentPresenterMain/ /Trigger Trigger Propertyhc:IconElement.GeometryValue{x:Null} Setter PropertyVisibilityValueCollapsedTargetNamePathMain/ Setter PropertyMarginValue0TargetNameContentPresenterMain/ /Trigger /ControlTemplate.Triggers /ControlTemplate /Setter.Value /Setter Style.Triggers Trigger PropertyIsMouseOverValueTrue Setter PropertyOpacityValue.9/ /Trigger Trigger PropertyIsPressedValueTrue Setter PropertyOpacityValue.6/ /Trigger Trigger PropertyIsEnabledValueFalse Setter PropertyOpacityValue0.4/ /Trigger /Style.Triggers/Style/hc:Window.Resources/hc:Window其中样式中设置一个默认颜色。!--给local:IconElement.Foreground设置一个默认颜色--SetterPropertylocal:IconElement.ForegroundValue{DynamicResource PrimaryTextBrush}/页面使用附加属性在案例项目中引入并设置local:IconElement.Foreground为Input2GeometryBrush。ButtonStyle{StaticResource ButtonBaseStyleX}WidthAutoPadding12,6Height36FontSize14Content多色样例hc:IconElement.Geometry{StaticResource InputGeometry}local:IconElement.Foreground{StaticResource Input2GeometryBrush}hc:IconElement.Width24hc:IconElement.Height20/Button比对效果如下当然不这样弄行不行也可以通过三方开源nuget包SharpVectors直接使用svg文件减少重复Brush对象的创建。总结以上就是在HandyControl库中不引入其他三方库时实现多彩路径svg按钮的解决方案这里主要是对GeometryGroup、Style覆写、DrawingBrush、DrawingGroup、DrawingGeometry以及附加属性的整合应用内容有点绕目的也就是为了多彩路径。

相关新闻