style plantillas para gratis wpf data-binding styles

plantillas - Encuadernación para estilos WPF



wpf templates free (4)

Estoy intentando crear un control personalizado, un botón, que tendrá varios estilos aplicados dependiendo del valor de una propiedad dentro del contexto de datos.

Lo que estaba pensando es usar algo similar a:

<Button Style="{Binding Path=ButtonStyleProperty, Converter={StaticResource styleConverter}}" Text="{Binding Path=TextProp}" />

Y en código ... Implemente un IValueConverter que haga algo similar al código siguiente en el método ConvertTo :

switch(value as ValueEnums) { case ValueEnums.Enum1: FindResource("Enum1ButtonStyle") as Style; break; ... and so on. }

Sin embargo, no estoy del todo seguro acerca de cómo sacar el objeto de estilo e incluso si esto es posible en absoluto ...

Mientras tanto, lo que estoy haciendo es manejar el evento DataContextChanged , luego adjuntar un controlador al evento PropertyChanged del objeto que está vinculado al botón, y luego ejecutar la instrucción switch allí.

No es del todo perfecto, pero hasta que encuentre una solución mejor, parece que es lo que tendré que usar.


Para aquellos de nosotros que no podemos usar el convertidor multivalor (te estoy viendo SL4 y WP7 :), gracias a la respuesta de Steven encontré una manera de usar un convertidor de valor ordinario.

La única suposición es que el valor del estilo está contenido dentro de la propiedad del estilo que se está configurando.

Entonces, si está usando el patrón MVVM, se supone que el valor del estilo (como TextSmall, TextMedium, TextLarge) forma parte del modelo de vista, y todo lo que tiene que hacer es pasar el parámetro del convertidor que define el nombre del estilo.

Por ejemplo, supongamos que su modelo de vista tiene propiedad:

public string ProjectNameStyle { get { return string.Format("ProjectNameStyle{0}", _displaySize.ToString()); } }

Estilo de aplicación:

<Application.Resources> <Style x:Key="ProjectNameStyleSmall" TargetType="TextBlock"> <Setter Property="FontSize" Value="40" /> </Style> <Style x:Key="ProjectNameStyleMedium" TargetType="TextBlock"> <Setter Property="FontSize" Value="64" /> </Style> <Style x:Key="ProjectNameStyleLarge" TargetType="TextBlock"> <Setter Property="FontSize" Value="90" /> </Style>

Vista XAML:

<TextBlock Text="{Binding Name}" Style="{Binding ., Mode=OneWay, Converter={cv:StyleConverter}, ConverterParameter=ProjectNameStyle}">

Con su clase StyleConverter implementando IValueConverter:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (targetType != typeof(Style)) { throw new InvalidOperationException("The target must be a Style"); } var styleProperty = parameter as string; if (value == null || styleProperty == null) { return null; } string styleValue = value.GetType() .GetProperty(styleProperty) .GetValue(value, null) .ToString(); if (styleValue == null) { return null; } Style newStyle = (Style)Application.Current.TryFindResource(styleValue); return newStyle; }

Tenga en cuenta que este es el código WPF, ya que el convertidor se deriva de un MarkupExtension así como de IValueConverter, pero funcionará en SL4 y WP7 si usa recursos estáticos y agrega un poco más de trabajo porque el método TryFindResource no existe.

Espero que ayude a alguien, ¡y gracias de nuevo a Steven!


Parece que necesitas usar la clase DataTrigger . Le permite aplicar diferentes estilos a su botón en función de su contenido.

Por ejemplo, el siguiente estilo cambiará la propiedad de fondo del botón a rojo según el valor de la propiedad del objeto de contexto de datos

<Style x:Key="ButtonStyle" TargetType="{x:Type Button}"> <Style.Triggers> <DataTrigger Binding="{Binding Path="Some property"}" Value="some property value"> <Setter Property="Background" Value="Red"/> </DataTrigger> </Style.Triggers> </Style>


Si desea reemplazar todo el estilo (en lugar de solo elementos de él), probablemente estará almacenando esos estilos en los recursos. Debería poder hacer algo como:

<Button> <Button.Style> <MultiBinding Converter="{StaticResource StyleConverter}"> <MultiBinding.Bindings> <Binding RelativeSource="{RelativeSource Self}"/> <Binding Path="MyStyleString"/> </MultiBinding.Bindings> </MultiBinding> </Button.Style> </Button>

Al usar un enlace múltiple y usar el yo como primer enlace, podemos buscar recursos en nuestro convertidor. El convertidor necesita implementar IMultiValueConverter (en lugar de IValueConverter) y puede verse más o menos así:

class StyleConverter : IMultiValueConverter { public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) { FrameworkElement targetElement = values[0] as FrameworkElement; string styleName = values[1] as string; if (styleName == null) return null; Style newStyle = (Style)targetElement.TryFindResource(styleName); if (newStyle == null) newStyle = (Style)targetElement.TryFindResource("MyDefaultStyleName"); return newStyle; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

No es algo que hago muy a menudo, pero debería funcionar desde la memoria :)


ViewModel

private Style _dynamicStyle = (Style)Application.Current.FindResource("Style1"); public Style DynamicStyle { get { return _dynamicStyle; } set { _dynamicStyle = value; OnPropertyChanged("DynamicStyle"); } } public event PropertyChangedEventHandler PropertyChanged; private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } }

Implemente una propiedad en su ViewModel y luego cambie dinámicamente el estilo donde quiera, como a continuación.

DynamicStyle=(Style)Application.Current.FindResource("Style2");// you can place this code where the action get fired

Ver

Luego configure el valor de DataContext y luego implemente el siguiente código en su vista

<Button Style="{Binding DynamicStyle,Mode=TwoWay}"/>