Как удалить границу ButtonChrome (при определении шаблона границы)?
Я последовал за ChrisF
здесь и написал простую демонстрацию.
... откройте свой проект в Expression Blend, выберите кнопку, а затем щелкните правой кнопкой мыши и выберите "Редактировать шаблон > Изменить Копия..". Это копирует существующие шаблон в один, который вы можете изменить. Это проще, если вы создадите его в ресурсе словарь.
И я вижу шаблон заставки на экране, как показано ниже снимок экрана (The ButtonChrome в ресурсе).
Я хочу удалить границу с белым градиентом ButtonChrome И сохранить все остальное пользовательского интерфейса кнопки как-есть. Как я могу это сделать?
пс. Чтобы сделать проблему простой, я использую ButtonChrome как обычный элемент управления на моем представлении. Я просматриваю свойства, но по-прежнему не знаю, где удалить "белую" границу.
(Используется ButtonChrome)
![alt text]()
(ButtonChrome в ресурсе)
![alt text]()
Ответы
Ответ 1
Я не думаю, что есть простой способ избавиться от этой Белой границы. Фактическая подпрограмма называется DrawInnerBorder и ее вызываемой из OnRender в ButtonChrome.
protected override void OnRender(DrawingContext drawingContext)
{
Rect bounds = new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight);
this.DrawBackground(drawingContext, ref bounds);
this.DrawDropShadows(drawingContext, ref bounds);
this.DrawBorder(drawingContext, ref bounds);
// This one draws the white Rectangle
this.DrawInnerBorder(drawingContext, ref bounds);
}
private void DrawInnerBorder(DrawingContext dc, ref Rect bounds)
{
if ((base.IsEnabled || this.RoundCorners) && ((bounds.Width >= 4.0) && (bounds.Height >= 4.0)))
{
Pen innerBorderPen = this.InnerBorderPen;
if (innerBorderPen != null)
{
dc.DrawRoundedRectangle(null, innerBorderPen, new Rect(bounds.Left + 1.5, bounds.Top + 1.5, bounds.Width - 3.0, bounds.Height - 3.0), 1.75, 1.75);
}
}
}
Как мы видим, нет свойства отключить это.
Вы можете проверить его, установив IsEnabled="False"
и RoundCorners="False"
на ButtonChrome или установив ширину или высоту примерно на 3.99 и "Белая граница" уходит.
Обновление
Чтобы отключить внутреннюю границу ButtonChrome, вы можете создать свой собственный ButtonChrome, который добавляет это свойство. К сожалению, ButtonChrome запечатан, поэтому мы не можем наследовать его. Я попытался скопировать весь класс и добавить Property DisableInnerBorder и, похоже, работает. Вы можете использовать его так:
<local:MyButtonChrome ...
DisableInnerBorder="True">
Кроме того, он работает так же, как обычный ButtonChrome, и вы также можете добавить другие свойства и т.д., которые вы можете захотеть. Могут быть недостатки этого метода, о которых я не думал, но для небольшого теста он работал нормально.
По-видимому, 937 строк кода было слишком много для публикации на SO:) Я загрузил MyButtonChrome.cs здесь: http://www.mediafire.com/?wnra4qj4qt07wn6
Ответ 2
Одна из великих фетартов WPF - это способность использовать поведение элемента управления, полностью меняя внешний вид этого элемента управления. Вы можете просто удалить хром и создать настраиваемое представление, соответствующее вашим требованиям.
Пример
<Style x:Key="NoChromeButton" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
<Setter Property="Opacity" TargetName="Chrome" Value="0.5"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Проверьте это тоже
http://www.designerwpf.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/
Теперь эта ссылка работает:
http://www.designersilverlight.com/2008/03/27/wpf-designers-guide-to-styles-and-templates/
Ответ 3
Не следует пытаться настроить ButtonChrome. * Классы Chrome являются тематическими, т.е. Они содержат реализацию определенной темы Windows, и вы не можете ее переопределить. Посмотрите на объявление пространства имен Microsoft_Windows_Themes в своем ресурсном словаре - оно, вероятно, содержит нечто вроде PresentationFramework.Aero...
Что вы должны делать в своих пользовательских шаблонах, это использовать обычную Border вместо ButtonChrome и определять триггеры, которые изменят свой фон и т.д., когда кнопка нажата или зависнет.
Вот пример:
<Style x:Key="BaseButtonStyle"
TargetType="{x:Type ButtonBase}">
<Setter Property="FocusVisualStyle"
Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="Background"
Value="{StaticResource ButtonNormalBackground}" />
<Setter Property="BorderBrush"
Value="{StaticResource ButtonNormalBorder}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Foreground"
Value="{StaticResource ButtonNormalForeground}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Padding"
Value="5,2,5,2" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true"
CornerRadius="2">
<ContentPresenter Margin="{TemplateBinding Padding}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver"
Value="True">
<Setter Property="Background"
Value="{StaticResource ButtonHoverBackground}" />
<Setter Property="Foreground"
Value="{StaticResource ButtonHoverForeground}" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<Setter Property="Background"
Value="{StaticResource ButtonPressedBackground}" />
<Setter Property="Foreground"
Value="{StaticResource ButtonPressedForeground}" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter Property="Background"
Value="{StaticResource ButtonHoverBackground}" />
<Setter Property="Foreground"
Value="{StaticResource ButtonNormalForeground}" />
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="#ADADAD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
Ответ 4
Я понимаю, что это старый поток, но я нашел его, когда пытался сделать то же самое и не нашел отличных решений. Я думал, что опубликую то, что я придумал, если это поможет кому-то еще.
То, что я хотел, было плоскими кнопками, которые использовали обычный хром, когда мы были перепутаны. Лучший способ, который я смог найти, - обмануть и использовать два ContentPresenters внутри Grid с двумя строками. Один контент-презентатор находится внутри обычного ButtonChrome, а один находится внутри границы. Одновременно отображается только одна строка сетки, а сеттер в триггере IsMouseOver определяет, какой из них показан.
<Window.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeDashArray="1 2" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" Margin="2"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#F3F3F3" Offset="0"/>
<GradientStop Color="#EBEBEB" Offset="0.5"/>
<GradientStop Color="#DDDDDD" Offset="0.5"/>
<GradientStop Color="#CDCDCD" Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder" Color="Transparent"/>
<Style x:Key="ActionButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
<Setter Property="Background" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="ContentWithChrome" Height="0"></RowDefinition>
<RowDefinition x:Name="ContentWithBorder" Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Themes:ButtonChrome Grid.Row="0" x:Name="Chrome" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}" RenderDefaulted="{TemplateBinding IsDefaulted}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Themes:ButtonChrome>
<Border Grid.Row="1" Margin="0,2,0,2">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Height" TargetName="ContentWithChrome" Value="Auto" />
<Setter Property="Height" TargetName="ContentWithBorder" Value="0" />
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="RenderDefaulted" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="ToggleButton.IsChecked" Value="true">
<Setter Property="RenderPressed" TargetName="Chrome" Value="true"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="#ADADAD"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Ответ 5
если вы хотите просто избежать WhiteBorder, вам нужно просто изменить BorderBrush = Прозрачный
<Microsoft_Windows_Themes:ButtonChrome x:Name="Chrome" SnapsToDevicePixels="true"
Background="{TemplateBinding Background}" BorderBrush="Transparent"
RenderDefaulted="{TemplateBinding IsDefaulted}" RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
</Microsoft_Windows_Themes:ButtonChrome>
Если вы хотите изменить некоторые другие вещи, вам нужно создать собственный ControlTemplate
пожалуйста, эта ссылка
http://mark-dot-net.blogspot.com/2007/07/creating-custom-wpf-button-template-in.html
здесь у них разные шаблоны кнопок
Ответ 6
После обсуждения с Meleak некоторое время, наконец, я получил окончательное решение для моего вопроса! Спасибо, Мелик!
Здесь можно скачать исходные коды решений.
Ответ 7
Опция также должна использовать другую библиотеку, такую как telerik или xceed (также доступная для свободного коммерческого использования). В моем решении я создал класс a, полученный из Xceed.Wpf.Toolkit.Chromes.ButtonChrome(Microsoft ButtonChrome запечатан).
В моем ResourceDictionary я реализовал стиль для Combobox, созданный Blend для VS.
В ControlTemplate для ToggleButton я выполнил следующий код:
<ControlTemplate TargetType="{x:Type ToggleButton}">
<p:ButtonChromeManaged x:Name="Chrome"
Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"
Background="Transparent"
BorderBrush="Transparent"
CornerRadius="0"
SnapsToDevicePixels="true">
<p:ButtonChromeManaged.Template>
<ControlTemplate TargetType="{x:Type p:ButtonChromeManaged}">
<Border Background="Red">
<Path x:Name="Arrow"
Margin="0,1,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="{StaticResource DownArrowGeometry}"
Fill="Black" />
</Border>
</ControlTemplate>
</p:ButtonChromeManaged.Template>
Здесь вы можете увидеть только самые неустойчивые stuf. Ваша DownArrowGeometry и т.д., Вы знаете, что нужно делать.
Я надеюсь, что это может помочь кому-то; -)