studio - ¿Cómo dibujar formas o líneas dentro de un botón WPF de ese tamaño al control sin causar que el botón se expanda para siempre?
botones redondos visual studio 2017 (3)
Tuve un rápido Google y una rápida mirada alrededor de StackOverflow, pero no pude encontrar a nadie más que se encontrara con este problema.
Quiero crear un botón de cerrar con una pequeña X en él. El botón de cerrar hará cosas como desvanecerse cuando estás sobre el elemento que lo contiene, cambiar de color cuando pases el mouse y toda la belleza habitual de WPF. En pocas palabras, no parece que sea tan difícil, pero me encuentro con uno de los problemas más extraños que he tenido hasta ahora.
Este es mi estilo XAML para el botón:
<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>
Y creo mi botón, solo como una prueba, así:
<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>
Y aquí es donde todo va horriblemente mal. Cuando ejecuta la aplicación, el botón se expandirá infinitamente, un píxel a la vez, horizontalmente y verticalmente hasta que llegue al alto de la ventana.
Ahora puedo entender por qué está sucediendo esto: las Líneas en realidad van una unidad más allá del ancho y la altura de la Rejilla, haciendo que la Rejilla se expanda en una unidad, luego hay una retransmisión, el enlace de datos hace que las líneas vuelvan a dibujarse, ad infinitum.
Entonces, para tratar de lidiar con esto, decidí poner una en la grilla pero luego, sin importar lo que haga con HorizontalAlignment y VerticalAlignment, termino con Canvas y Grid teniendo ancho y alto cero, lo que significa que no obtener mi cruz, que es masivamente irritante. Si me sumo a las propiedades ActualWidth y ActualHeight del botón, simplemente termino con una X que tiene la esquina superior izquierda centrada en el centro del botón.
¿Alguien tiene alguna idea de lo que puedo hacer para arreglar esto? Estaría muy agradecido por cualquier información: WPF sigue siendo una bestia bastante nueva para mí.
¡Gracias!
No debería tener que recurrir a enlaces solo para hacer diseño. Como ha visto, los enlaces y los sistemas de diseño no funcionan en conjunto (creo que la unión de datos tiene prioridad sobre el diseño, pero en su caso, el diseño causa otro enlace de datos)
Deberías ser capaz de obtener una X estirable y bonita con solo un Camino:
<Path Data="M0,0 L1,1 M0,1 L1,0" Stretch="Uniform" Stroke="Red" />
Si desea que se escale con el tamaño del botón en lugar de estirarlo (la escala afecta el ancho aparente del trazo), simplemente use un ViewBox
En lugar de vinculante, le sugiero que utilice las propiedades Stretch and Margin o Padding, como la siguiente
<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>
Actualizar
Entonces, el problema con su ejemplo parece ser el alto y el ancho mínimos. Si no puede usar alto y ancho, sugeriría algo como lo siguiente
<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>
Gracias a todos. La solución de Rob con Viewbox
resultó ser la respuesta. El botón se comporta perfectamente, incluso si MinHeight
atributos MidWidth
y MinHeight
de la declaración Button en MainWindow.xaml .
Aquí está mi estilo modificado:
<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>
¡Gracias de nuevo por todas las sugerencias!