WPF入门——Converter、XAML和Style

System.Windows.Data.IValueConverter 接口

派生
System.Activities.Core.Presentation.GenericTypeArgumentConverter
System.Activities.Presentation.Converters.ArgumentToExpressionConverter
System.Activities.Presentation.Converters.ModelPropertyEntryToModelItemConverter
System.Activities.Presentation.Converters.ModelPropertyEntryToOwnerActivityConverter
System.Activities.Presentation.Converters.ModelToObjectValueConverter
System.Windows.Controls.AlternationConverter
System.Windows.Controls.BooleanToVisibilityConverter
System.Windows.Controls.Ribbon.Primitives.RibbonWindowSmallIconConverter
System.Windows.Documents.ZoomPercentageConverter
System.Windows.Navigation.JournalEntryListConverter

该接口只有两个方法,
Convert(Object, Type, Object, CultureInfo)
ConvertBack(Object, Type, Object, CultureInfo)
用户实现该接口之后可以创建一些类型转换,举个简单例子:参数是int返回string。

Binding

System.Windows.Data.binding有一个Converter属性,如下面的例子:

Visibility=
"{Binding ElementName=Window,
Path=WindowState, 
Converter={StaticResource MaxButtonConverter}, 
ConverterParameter=Max, 
Mode=OneWay}"

上述代码是一个button的可视属性的设置,代码创建了一个binding实例(xaml的本质就是创建实例),binding了VisibilityWindow.WindowState,binding的时候通过convertor转换Window.WindowState类型到Visibility类型。
上面的converter的代码如下:

/// <summary>
/// 切换最大化按钮,把WindowState的枚举类型转换成Visibility
/// </summary>
public class MaxButtonConverter : IValueConverter
{
	public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
	{
		if (parameter.ToString() == "Max")
		{
			if ((WindowState)value != WindowState.Maximized)
			{
				return "Visible";
			}
			return "Collapsed";
		}
		if ((WindowState)value != WindowState.Maximized)
		{
			return "Collapsed";
		}
		return "Visible";
	}

	public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
	{
		return null;
	}
}   

xaml的一点说明

这里说一下xaml的一个语法,
<Button Width="45" Height="32" Style="{DynamicResource normalButtonStyle}" Background="#00FFFFFF">
直接在“引号”中赋值的,是赋值了button的属性
例如Width="45"实际上用代码表示就是button.Width = 45

引号中带花括号的,是赋值了一个实例,上面的Style就是赋值了一个资源字典中的实例,赋值方式是动态。

Visibility=
"{Binding ElementName=Window,
Path=WindowState, 
Converter={StaticResource MaxButtonConverter}, 
ConverterParameter=Max, 
Mode=OneWay}"

这里也是赋值了一个对象,不过这个对象是新创建的,新创建的binding对象的时候赋值了一些属性给binding对象(path、convertor等)

Style

我们可以定义一个资源字典,添加字典到Application的属性中,这样每个控件都可以随时根据key使用定义在资源字典中的Style。
一个Style定义的例子:

    <Style x:Key="ContextMenuStyle" TargetType="{x:Type ContextMenu}">
    <Setter Property="UIElement.SnapsToDevicePixels" Value="True" />
    <Setter Property="FrameworkElement.OverridesDefaultStyle" Value="True" />
    <Setter Property="Grid.IsSharedSizeScope" Value="True" />
    <Setter Property="ContextMenu.HasDropShadow" Value="True" />
    <Setter Property="MaxWidth" Value="250" />
    <Setter Property="Margin" Value="0,10" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="{x:Type ContextMenu}">
          <Border Name="Border" Background="{TemplateBinding Background}" BorderThickness="10">
            <UIElement.Effect>
              <DropShadowEffect BlurRadius="10" Opacity="0.2" ShadowDepth="0" />
            </UIElement.Effect>
            <ScrollViewer Style="{DynamicResource for_scrollviewer}" Margin="0,8">
              <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" />
            </ScrollViewer>
          </Border>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

上面摘自一个资源字典,实际上是定义了一个Style类型的对象实例,并添加到了资源字典,key是ContextMenuStyle
style类有如下属性和方法:

        public Style();
        public Style(Type targetType);
        public Style(Type targetType, Style basedOn);

        public bool IsSealed { get; }
        [Ambient]
        [Localizability(LocalizationCategory.NeverLocalize)]
        public Type TargetType { get; set; }
        [Ambient]
        [DefaultValue(null)]
        public Style BasedOn { get; set; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public TriggerCollection Triggers { get; }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SetterBaseCollection Setters { get; }
        [Ambient]
        public ResourceDictionary Resources { get; set; }

        public override int GetHashCode();
        public void RegisterName(string name, object scopedElement);
        public void Seal();
        public void UnregisterName(string name);

Trigger、Setters等介绍:

setter类,拥有value(object)、property等属性

    [XamlSetMarkupExtension("ReceiveMarkupExtension")]
    [XamlSetTypeConverter("ReceiveTypeConverter")]
    public class Setter : SetterBase, ISupportInitialize
    {
        public Setter();
        public Setter(DependencyProperty property, object value);
        public Setter(DependencyProperty property, object value, string targetName);

        [Ambient]
        [DefaultValue(null)]
        [Localizability(LocalizationCategory.None, Modifiability = Modifiability.Unmodifiable, Readability = Readability.Unreadable)]
        public DependencyProperty Property { get; set; }
        [DependsOn("Property")]
        [DependsOn("TargetName")]
        [Localizability(LocalizationCategory.None, Readability = Readability.Unreadable)]
        [TypeConverter(typeof(SetterTriggerConditionValueConverter))]
        public object Value { get; set; }
        [Ambient]
        [DefaultValue(null)]
        public string TargetName { get; set; }

        public static void ReceiveMarkupExtension(object targetObject, XamlSetMarkupExtensionEventArgs eventArgs);
        public static void ReceiveTypeConverter(object targetObject, XamlSetTypeConverterEventArgs eventArgs);
    }
原文地址:https://www.cnblogs.com/feipeng8848/p/12515440.html