将属性绑定到ResourceDictionary上定义的样式以消除代码重复
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将属性绑定到ResourceDictionary上定义的样式以消除代码重复相关的知识,希望对你有一定的参考价值。
我有以下XAML代码:
<Window x:Class="LinkButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:LinkButton"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
DataContext="{StaticResource MainWindowVM}">
<Window.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10" />
</Style>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="ddk" />
<TextBlock Grid.Row="0" Grid.Column="1" >
<Hyperlink Command="{Binding Link}"
CommandParameter="{Binding}"
Foreground="Blue" >
<Hyperlink.Inlines>
<TextBlock>
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="{Binding Description01.Header}" />
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0" Text="dde" />
<TextBlock Grid.Row="1" Grid.Column="1">
<Hyperlink Command="{Binding Link}"
CommandParameter="{Binding}"
Foreground="Blue" >
<Hyperlink.Inlines>
<TextBlock>
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="{Binding Description11.Header}" />
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
</Grid>
</Window>
和C#代码:
public class TestCommand : ICommand
{
public delegate void ICommandOnExecute(object parameter);
public delegate bool ICommandOnCanExecute(object parameter);
private ICommandOnExecute _execute;
private ICommandOnCanExecute _canExecute;
public TestCommand(ICommandOnExecute onExecuteMethod, ICommandOnCanExecute onCanExecuteMethod)
{
_execute = onExecuteMethod;
_canExecute = onCanExecuteMethod;
}
#region ICommand Members
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public bool CanExecute(object parameter)
{
return _canExecute.Invoke(parameter);
}
public void Execute(object parameter)
{
_execute.Invoke(parameter);
}
#endregion
}
public class LongDescription
{
public string Header { get; }
public string Description { get; }
public LongDescription(string header, string description)
{
Header = header;
Description = description;
}
}
public class MainWindowVM
{
public ICommand Link => new TestCommand(ExecuteCommand1, CanExecuteCommand1);
public LongDescription Description11 => new LongDescription("cell11", "result cell11");
public LongDescription Description01 => new LongDescription("cell01", "result cell01");
public bool CanExecuteCommand1(object parameter)
{
return true;
}
public void ExecuteCommand1(object parameter)
{
MessageBox.Show("Executing command 1");
}
}
很明显,我在XAML(<Hyperlink.Inlines>
等)中有重复的代码。我想重构它,以便消除代码重复。为此,我正在考虑在<Hyperlink.Inlines>
中定义ResourceDictionary
样式,然后将其绑定到MainWindowVM
中的适当属性。
但我不确定如何做,任何想法?
您可以像这样在ResourceDictionary中轻松移动Style
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Key is required to identify the Style -->
<Style x:Key="Bind01" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Description01.Header}" />
</Style>
<Style x:Key="Bind11" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding Description11.Header}" />
</Style>
</ResourceDictionary>
并在窗口中合并字典以使用样式
去
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="YourDictionaryHere"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="10" />
</Style>
</ResourceDictionary>
</Window.Resources>
使用
<TextBox Style="{DynamicResource Bind01}"/>
简单化
我建议将变量Bindings直接写入Control并将其余部分定义为Style,而不是将变量Binding放入样式(或字典)中。
更具体:以下标记将绑定字符串显示为Hyperlink
,单击时执行ICommand。
<TextBlock>
<Hyperlink Command="{Binding Link}"
CommandParameter="{Binding}"
Foreground="Blue" >
<Hyperlink.Inlines>
<TextBlock>
<TextBlock.Style>
<Style>
<Setter Property="TextBlock.Text" Value="{Binding Description11.Header}" />
</Style>
</TextBlock.Style>
</TextBlock>
</Hyperlink.Inlines>
</Hyperlink>
</TextBlock>
我们可以为Button定义一个Style,它看起来(并且确实)相同,但是变量Binding可以通过Content
直接设置。
按钮样式
<Style x:Key="LinkStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<TextBlock>
<Hyperlink Command="{Binding Link}" CommandParameter="{Binding}">
<Run Text="{TemplateBinding Content}"/>
</Hyperlink>
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
将样式应用于网格中的元素(将TextBlock
替换为样式按钮)
<TextBlock Grid.Row="0" Grid.Column="0" Text="ddk" />
<Button Grid.Row="1" Grid.Column="1"
Content="{Binding Description01.Header}"
Style="{DynamicResource LinkStyle}">
<TextBlock Grid.Row="1" Grid.Column="0" Text="dde" />
<Button Grid.Row="1" Grid.Column="1"
Content="{Binding Description11.Header}"
Style="{DynamicResource LinkStyle}">
屏幕(虚线为网格线)
编辑
要设置Command
的Hyperlink
,我们使用Button的Command
属性来设置Binding。因此,我们必须在我们的风格中添加一个TemplateBinding
。用Command
替换“Hard Coded”TemplateBinding
到Button
Command
。对Commandparameter执行相同操作。
<Hyperlink Command="{TemplateBinding Command}"
CommandParameter="{Templatebinding Commandparameter}"
Foreground="Blue" >
并设置Command
和CommandParameter
在风格的Button
<TextBlock Grid.Row="0" Grid.Column="0" Text="ddk" />
<Button Grid.Row="1" Grid.Column="1"
Content="{Binding Description01.Header}"
Command="{Binding YOURCOMMANDHERE}"
CommandParameter="{YOURPARAMETER}"
Style="{DynamicResource LinkStyle}">
<TextBlock Grid.Row="1" Grid.Column="0" Text="dde" />
<Button Grid.Row="1" Grid.Column="1"
Content="{Binding Description11.Header}"
Command="{Binding YOUROTHERCOMMANDHERE}"
CommandParameter="{YOUROTHERPARAMETER}"
Style="{DynamicResource LinkStyle}">
以上是关于将属性绑定到ResourceDictionary上定义的样式以消除代码重复的主要内容,如果未能解决你的问题,请参考以下文章
从 Catel WPF UserControl 中的 ResourceDictionary 中绑定