plantillas gratis wpf c#-3.0 themes styles

gratis - wpf templates



¿Cómo configurar el estilo de ventana WPF predeterminado en app.xaml? (8)

Estoy tratando de establecer el estilo predeterminado para cada ventana en mi aplicación Windows WPF en mi app.xaml. Hasta ahora tengo esto en app.xaml:

<Application.Resources> <ResourceDictionary> <Style x:Key="WindowStyle" TargetType="{x:Type Window}"> <Setter Property="Background" Value="Blue" /> </Style> </ResourceDictionary> </Application.Resources>

Puedo hacer que la ventana aparezca con este estilo cuando ejecuto la aplicación (pero no es VS Designer) al decirle específicamente a la ventana que use este estilo a través de:

Style="{DynamicResource WindowStyle}

Esto funciona, pero no es ideal. Entonces, ¿cómo puedo:

  1. ¿Todas las ventanas usan automáticamente el estilo (para que no tenga que especificarlo en cada ventana)?
  2. ¿El diseñador VS muestra el estilo?

¡Gracias!


El diseñador no funciona porque está especificando un DynamicResource. Cambie esto a StaticResource y todo estará bien.

Para aplicar a todas las ventanas, debe eliminar la clave x: del estilo. Establecer TargetType establece implícitamente la x: Key a lo que está en TargetType. Sin embargo, en mis pruebas, esto no funciona, entonces lo estoy investigando.

Si configuro TargetType en x: escriba TextBlock, el diseñador funciona perfectamente, simplemente parece ser la ventana que muestra un comportamiento diferente.


Para agregar a lo que Ray dice:

Para los estilos, debe proporcionar una clave / ID o especificar un TargetType.

Si un FrameworkElement no tiene un estilo explícitamente especificado, siempre buscará un recurso de estilo, usando su propio tipo como la clave
- Programación de WPF (Sells, Griffith)

Si proporciona un TargetType, todas las instancias de ese tipo tendrán el estilo aplicado. Sin embargo, los tipos derivados no ... parece. <Style TargetType="{x:Type Window}"> no funcionará para todas sus derivaciones / ventanas personalizadas. <Style TargetType="{x:Type local:MyWindow}"> se aplicará solo a MyWindow. Entonces las opciones son

  • Use un estilo con clave que especifique como la propiedad de Estilo de cada ventana en la que desea aplicar el estilo. El diseñador mostrará la ventana con estilo.

.

<Application.Resources> <Style x:Key="MyWindowStyle"> <Setter Property="Control.Background" Value="PaleGreen"/> <Setter Property="Window.Title" Value="Styled Window"/> </Style> </Application.Resources> ... <Window x:Class="MyNS.MyWindow" Style="{StaticResource MyWindowStyleKey}"> ...

  • O puede derivar de una clase BaseWindow personalizada (que tiene sus propias peculiaridades ), donde establece la propiedad Style durante la etapa Ctor / Initialization / Load una vez. Todas las Derivaciones tendrían automáticamente el estilo aplicado. Pero el diseñador no se dará cuenta de tu estilo. Debes ejecutar tu aplicación para ver el estilo que se está aplicando. Supongo que el diseñador solo ejecuta InitializeComponent (que es código generado automáticamente / por el diseñador) así que se aplica XAML pero no es personalizado. código detrás.

Así que diría que los estilos explícitamente especificados son los menos efectivos. De todos modos, puedes cambiar los aspectos del Estilo centralmente.


Para aquellos que luchan con una solución al problema: ¿Cómo puedo hacer que un estilo personalizado se aplique automáticamente a todos mis tipos derivados de Windows? A continuación está la solución que se me ocurrió

NOTA: Realmente no quería derivarme del tipo Window o tener que insertar XAML en cada ventana para forzar una actualización de estilo, etc. por razones específicas de mi proyecto (los consumidores de mi producto usamos nuestra biblioteca genérica de estilo reutilizable y creamos la suya propia). diseño / ventanas, etc.) así que estaba realmente motivado para encontrar una solución que funcionase que estaba dispuesta a vivir con cualquier efecto secundario

Necesita iterar a través de todas las ventanas instanciadas y simplemente forzarlas a usar el nuevo estilo personalizado que ha definido para el tipo de ventana. Esto funciona muy bien para las ventanas que ya están abiertas, pero cuando se crea una instancia de una ventana o una ventana secundaria, no sabrá usar el tipo nuevo / personalizado que se ha declarado para su tipo base; el tipo de ventana vainilla. Así que lo mejor que se me ocurrió fue utilizar LostKeyBoardFocus en MainWindow para cuando pierde Focus to a ChildWindow (IOW cuando se ha creado una ventana hija) y luego invocar este FixupWindowDerivedTypes ().

Si alguien tiene una mejor solución para "detectar" cuando se crea una instancia de cualquier tipo de tipo derivado de la ventana y, por lo tanto, llamar a FixupWindowDerivedTypes () sería genial. Puede haber algo útil al manejar WM_WINDOWPOSCHANGING en esta área también.

Así que esta solución no es elegante, por decir, pero hace el trabajo sin tener que tocar ningún código o XAML relacionado con mis ventanas.

public static void FixupWindowDerivedTypes() { foreach (Window window in Application.Current.Windows) { //May look strange but kindly inform each of your window derived types to actually use the default style for the window type window.SetResourceReference(FrameworkElement.StyleProperty, DefaultStyleKeyRetriever.GetDefaultStyleKey(window)); } } } } //Great little post here from Jafa to retrieve a protected property like DefaultStyleKey without using reflection. http://themechanicalbride.blogspot.com/2008/11/protected-dependency-properties-are-not.html //Helper class to retrieve a protected property so we can set it internal class DefaultStyleKeyRetriever : Control { /// <summary> /// This method retrieves the default style key of a control. /// </summary> /// <param name="control">The control to retrieve the default style key /// from.</param> /// <returns>The default style key of the control.</returns> public static object GetDefaultStyleKey(Control control) { return control.GetValue(Control.DefaultStyleKeyProperty); } }


  1. guardará todos los estilos en un archivo xaml (ejemplo design.xaml)

  2. y luego llame a ese archivo (design.xaml) xaml en todas las páginas de esta manera

Me gusta:

<ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Design.xaml"/> </ResourceDictionary.MergedDictionaries>


Considerando la respuesta de Gishu , descubrí una solución más. Pero podría ser un poco extraño. Si usa el patrón MVVM, puede eliminar el código subyacente de su ventana y el marcado x: Class en el archivo XAML. Por lo tanto, obtendrá una instancia de ventana o su ventana personalizada pero no una instancia de la clase ''MainWindow'' derivada de la clase ''Ventana'' y marcada como parcial. Estoy creando una ventana similar a VS, así que tuve que heredar la clase de ventana y ampliar su funcionalidad. En ese caso, será posible crear una nueva clase de ventana como parcial que nos permita hacer código subyacente sin herencia.


Investigué esto por algunos días y lo hice funcionar a través del Constructor de mi clase de ventana personalizada:

public class KWindow : Window { public KWindow() { this.SetResourceReference(StyleProperty, typeof(KWindow)); } static KWindow() { DefaultStyleKeyProperty.OverrideMetadata(typeof(KWindow), new FrameworkPropertyMetadata(typeof(KWindow))); } public override void OnApplyTemplate() { base.OnApplyTemplate(); // gets called finally } }

Espero que ayude a alguien


Puede agregar este código a su archivo App.xaml.cs:

FrameworkElement.StyleProperty.OverrideMetadata(typeof(Window), new FrameworkPropertyMetadata { DefaultValue = Application.Current.FindResource(typeof(Window)) });

Después de esto, el estilo aplicado al tipo Window también se aplicará a todos los tipos derivados de Window


Sepa que esto es años después, pero dado que la pregunta todavía está aquí ...

  1. Cree un diccionario de recursos en su proyecto (haga clic con el botón derecho en el proyecto ...)

    Crearé una nueva carpeta bajo el Proyecto llamada "Activos" y pondré "resourceDict.XAML" en ella.

  2. Agregue el código a resourceDict.XAML:

    <Style x:Key="WindowStyle" Target Type="Window" > <Setter Property="Background" Value="Blue" /> </Style>

  3. En su archivo Project XAML, agregue lo siguiente en Ventana:

    <Window.Resources> <ResourceDictionary> <!-- Believe it or not the next line fixes a bug MS acknowledges --> <Style TargetType="{x:Type Rectangle}" /> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/Assets/resourceDict.XAML" /> </ResourceDictionary.MergedDictionaries> <ResourceDictionary> </Window.Resources>

    ref el siguiente sitio web: Problemas al hacer referencia a un diccionario de recursos que contiene un diccionario combinado "Hay un error: si todos sus estilos predeterminados están anidados en diccionarios combinados de tres niveles (o más profundos), el diccionario superior no se marca para que la búsqueda salte. El trabajo alternativo consiste en poner un estilo predeterminado a algo, cualquier cosa, en el diccionario raíz ". Y parece arreglar las cosas de manera confiable. Imagínate...

  4. Y finalmente, bajo Window, tal vez después del título, pero antes de la ventana final ''>'':

    Style="{DynamicResource windowStyle}"

  5. Y deberá agregar el código en los pasos 3 y 4 a cada proyecto al que desee aplicar el estilo.

  6. Si desea utilizar un fondo degradado en lugar de un color sólido, agregue el siguiente código a resourceDict.XAML:

    <LinearGradientBrush x:Key="windowGradientBackground" StartPoint="0,0" EndPoint="0,1" > <GradientStop Color= "AliceBlue" Offset="0" /> <GradientStop Color= "Blue" Offset=".75" /> </LinearGradientBrush>

  7. Y modifique su Style Setter para que el color de fondo se lea:

    <Setter Property="Background" Value="{DynamicResource windowGradientBackground}" />

Los pasos 3 y 4 deben repetirse en cada proyecto. El archivo XAML como se describió anteriormente, pero bueno, ¡obtienes Windows uniforme en toda la Solución! Y el mismo proceso podría aplicarse a cualquier control que desee tener un aspecto uniforme, botones, lo que sea.

Para cualquier persona que llegue tan tarde, espero que esto ayude, ya que estoy seguro de que los carteles originales lo descifraron hace años.

Pablo