Как нарисовать фигуру или линии внутри кнопки WPF такого размера для элемента управления, не заставляя кнопку расширяться навсегда?
у меня был быстрый Google и быстрый взгляд вокруг StackOverflow, но не мог найти никого, кто столкнулся с этой проблемой.
Я хочу создать кнопку закрытия с небольшим X в нем. Кнопка закрытия будет делать такие вещи, как исчезать и исчезать, когда вы зависаете над элементом, содержащим его, менять цвет при наведении мыши и все обычное очарование WPF. В итоге, не кажется, что это должно быть так сложно, но я сталкиваюсь с одной из самых странных проблем когда-либо прежде Я даже дошел до этой стадии.
вот мой стиль XAML для кнопки:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TabCloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Content">
<Setter.Value>
<Grid>
<Line Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"
X1="0"
Y1="0"
X2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualWidth, Mode=OneWay}"
Y2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualHeight, Mode=OneWay}"/>
<Line Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"
X1="0"
Y1="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualHeight, Mode=OneWay}"
X2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualWidth, Mode=OneWay}"
Y2="0"/>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
и я создаю свою кнопку, просто как тест, Вот так:
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="124" Width="569">
<Grid Background="#2b3c59">
<StackPanel Orientation="Horizontal">
<!-- Other controls removed for clarity -->
<Button Style="{DynamicResource TabCloseButtonStyle}"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Padding="2"
Margin="0, 10, 0, 0"
MinWidth="50"
MinHeight="50"></Button>
</StackPanel>
</Grid>
</Window>
и вот где все это идет ужасно неправильно. При запуске приложения кнопка будет расширяться бесконечно, по одному пикселю за раз, горизонтально и вертикально, пока не достигнет высоты окна.
теперь я могу понять, почему это происходит: линии фактически выходят на одну единицу за пределы ширины и высота сетки заставляет сетку расширяться на одну единицу, затем происходит ретрансляция, привязка данных заставляет линии перерисовываться, ad infinitum.
Итак, чтобы попытаться справиться с этим, я решил поместить a в сетку, но затем, независимо от того, что я делаю с HorizontalAlignment и VerticalAlignment, я в конечном итоге получаю как холст, так и сетку с нулевой шириной и высотой, что означает, что я не получаю свой крест, что очень раздражает. Если я привязываюсь к свойствам ActualWidth и ActualHeight кнопки я просто заканчиваю с X, который имеет верхний левый угол, центрированный по центру кнопки.
кто-нибудь вообще знает, что я могу сделать, чтобы исправить это? Я был бы чрезвычайно благодарен за любые указатели - WPF все еще довольно новый зверь для меня.
спасибо!
3 ответов
вам не нужно прибегать к привязкам, чтобы сделать макет. Как вы видели, привязки и системы компоновки не работают согласованно (я думаю, что привязка данных получает приоритет над компоновкой, но в вашем случае компоновка вызывает другую привязку данных)
вы должны быть в состоянии получить довольно красивый, растягивающийся X с просто путь:
<Path Data="M0,0 L1,1 M0,1 L1,0" Stretch="Uniform" Stroke="Red" />
Если вы хотите масштаб С размером кнопки вместо простирания (маштаб влияет на кажущуюся ширину хода), тогда как раз используйте ViewBox
вместо привязки я бы предложил использовать свойства Stretch и Margin или Padding, как показано ниже
<Grid Margin="2">
<Line X1="0" Y1="0" Y2="1" X2="1" Stroke="Black" Stretch="Fill" />
<Line Y1="1" X2="1" Stroke="Black" Stretch="Fill" />
</Grid>
обновление
таким образом, проблема с вашим примером, похоже, является минимальной высотой и шириной. Если вы не можете просто использовать высоту и ширину, я бы предложил что-то вроде следующего
<Grid MinHeight="{TemplateBinding MinHeight}" MinWidth="{TemplateBinding MinWidth}">
<Line X1="0" Y1="0" Y2="1" X2="1" Stroke="Black" Stretch="Fill" />
<Line Y1="1" X2="1" Stroke="Black" Stretch="Fill" />
</Grid>
спасибо всем. Решение Роба с Viewbox
получился ответ. Кнопка ведет себя отлично, даже если я удаляю MidWidth
и MinHeight
атрибуты из объявления кнопки в файл MainWindow.в XAML.
вот мой измененный стиль:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TabCloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Content">
<Setter.Value>
<Grid>
<Viewbox>
<Path Data="M0,0 L10,10 M0,10 L10,0"
Stretch="Uniform"
Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground, Mode=OneWay}" />
</Viewbox>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
еще раз спасибо за все предложения!