如何更改文本块背景?
How to change textblock background?
这是我的xaml structure
<stackpanel>
<textblock Text="A"></textblock>
<textblock Text="B"></textblock>
</stackpanel>
Stackpanel
,可以循环生成更多相同的结构
如何在单击时更改 texblock 的背景颜色?
更新:I just want change on xaml file not using C#.
默认我是黄色的,但是当我点击一个文本块时,它的背景会变成蓝色。
更新 2:如果单击 A,A 将变为蓝色,直到我单击另一个。
详情:
我点A(A is yellow)
,A会变成蓝色==> A是蓝色
我点击B(B is yellow and A is blue)
,B会变成蓝色,A会变成黄色
更新 3:这个怎么样?
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
问题同上
谢谢!
以编程方式:
textBlock1.Background = new SolidColorBrush(Colors.Yellow);
在XAML中:
<TextBlock Name="textBlock1">
<TextBlock.Background>
<SolidColorBrush Color="Yellow" />
</TextBlock.Background>
</TextBlock>
要在单击文本块时更改背景颜色,您应该使用带有触发器的自定义样式。这并不难,如果您将搜索或询问有关使用样式和触发器的信息。你绝对不应该在 XAML 设计模式中为此使用 C#。
使用 EventTrigger 和 Color Animation 您可以在 MouseDown 上更改 TextBlock 背景颜色或 MouseLeave
xaml代码
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Yellow" To="Blue" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Blue" To="Yellow" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock Text="A" Background="Yellow"></TextBlock>
<TextBlock Text="B" Background="Yellow"></TextBlock>
</StackPanel>
更新
使用 TextBox with 属性 IsReadOnly=True 而不是文本块。
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="IsReadOnly" Value="True"></Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="TextBox.GotFocus">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Yellow" To="Blue" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="TextBox.LostFocus">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Blue" To="Yellow" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBox Text="A"></TextBox>
<TextBox Text="A"></TextBox>
</StackPanel>
<TextBlock Text="Hello, styled world!" FontSize="28" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="Yellow"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
这很可能是您问题的解决方案。正如我指出的那样,由于您希望一个控件依赖于其他控件的各种要求的性质,因此无法实现仅 xaml 的解决方案。
你当然可以 fiddle 处理其余部分。
public class RadioTextblock : TextBlock
{
static RadioTextblock()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RadioTextblock), new FrameworkPropertyMetadata(typeof(RadioTextblock)));
}
public static readonly DependencyProperty GroupProperty = DependencyProperty.Register(
"Group", typeof (string), typeof (RadioTextblock), new PropertyMetadata(string.Empty));
public string Group
{
get { return (string) GetValue(GroupProperty); }
set { SetValue(GroupProperty, value); }
}
public static readonly DependencyProperty ActiveColorProperty = DependencyProperty.Register(
"ActiveColor", typeof (Brush), typeof (RadioTextblock), new PropertyMetadata(default(Brush)));
public Brush ActiveColor
{
get { return (Brush) GetValue(ActiveColorProperty); }
set { SetValue(ActiveColorProperty, value); }
}
public static readonly DependencyProperty RestorationColorProperty = DependencyProperty.Register(
"RestorationColor", typeof (Brush), typeof (RadioTextblock), new PropertyMetadata(default(Brush)));
public Brush RestorationColor
{
get { return (Brush) GetValue(RestorationColorProperty); }
set { SetValue(RestorationColorProperty, value); }
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// there may be a better hook for this. but i'm not writing custom controls that often. anything after styles are applied should be good
RestorationColor = Background;
}
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
RestoreOtherBackgrounds(this);
base.OnPreviewMouseDown(e);
}
private void RestoreOtherBackgrounds(RadioTextblock radioTextblock)
{
var topParent = GetTopMostParent(radioTextblock);
var controlsWithGroup = GetChildrenRecursive<RadioTextblock>(topParent).ToLookup(d => (string)d.GetValue(GroupProperty));
var similar = controlsWithGroup[radioTextblock.Group];
foreach (var match in similar)
{
if (match == radioTextblock)
{
match.Background = ActiveColor;
}
else
{
match.Background = match.RestorationColor;
}
}
}
private DependencyObject GetTopMostParent(RadioTextblock radioTextblock)
{
DependencyObject current = radioTextblock;
while (current != null)
{
var cParent = VisualTreeHelper.GetParent(current);
if (cParent == null || cParent == current)
break;
current = cParent;
}
return current;
}
private IEnumerable<T> GetChildrenRecursive<T>(DependencyObject current) where T : DependencyObject
{
T casted;
var childCount = VisualTreeHelper.GetChildrenCount(current);
for (int i = 0; i < childCount; i++)
{
var currentChild = VisualTreeHelper.GetChild(current, i);
casted = currentChild as T;
if(casted != null)
yield return casted;
foreach (var subChild in GetChildrenRecursive<T>(currentChild))
{
if (subChild != null)
yield return casted;
}
}
}
}
改变你的XAML
结构如下
xmlns:local="clr-namespace:your_assembly_Name"
.....
<StackPanel>
<StackPanel.Resources>
<local:BackgroundConverter x:Key="backgroundConverter"/>
<Style TargetType="TextBlock">
<EventSetter Event="MouseDown" Handler="TextBlockMouseDownEvent" />
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource backgroundConverter}">
<Binding Path="Name" RelativeSource="{RelativeSource Self}"/>
<Binding Path="SelectedTextBlockName"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<TextBlock x:Name="text1" Text="Header"/>
<TextBlock x:Name="text2" Text="Header"/>
<TextBlock x:Name="text3" Text="Header"/>
<TextBlock x:Name="text4" Text="Header"/>
</StackPanel>
使用以下 IMultiValueConverter
并在您的代码后面添加 TextBlockMouseDownEvent
事件处理程序和一个 DependencyProperty
。
////DependencyProperty
public string SelectedTextBlockName
{
get { return (string)GetValue(SelectedTextBlockNameProperty); }
set { SetValue(SelectedTextBlockNameProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedTextBlock. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedTextBlockNameProperty =
DependencyProperty.Register("SelectedTextBlockName", typeof(string), typeof(Class_Name), new PropertyMetadata(null));
.......
private void TextBlockMouseDownEvent(object sender, MouseButtonEventArgs e)
{
TextBlock txtBlock = sender as TextBlock;
if (txtBlock != null)
{
SelectedTextBlockName = txtBlock.Name;
}
}
.......
public class BackgroundConverter : IMultiValueConverter
{
/// <summary>
/// Values[0] = Name of TextBlock
/// values[1] = SelectedTextBlockName
/// If matches then it is selected
/// </summary>
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values[0] != null && values[1] != null && values[0].ToString() == values[1].ToString())
return new SolidColorBrush(Colors.Blue);
return new SolidColorBrush(Colors.White);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
如果您想设置默认的 SelectedTextBlock,那么只需设置您想要作为默认选择的 TextBlock 名称。
像这样:
SelectedTextBlockName = "text1";
这是我的xaml structure
<stackpanel>
<textblock Text="A"></textblock>
<textblock Text="B"></textblock>
</stackpanel>
Stackpanel
,可以循环生成更多相同的结构
如何在单击时更改 texblock 的背景颜色?
更新:I just want change on xaml file not using C#.
默认我是黄色的,但是当我点击一个文本块时,它的背景会变成蓝色。
更新 2:如果单击 A,A 将变为蓝色,直到我单击另一个。
详情:
我点A
(A is yellow)
,A会变成蓝色==> A是蓝色我点击B
(B is yellow and A is blue)
,B会变成蓝色,A会变成黄色
更新 3:这个怎么样?
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
<stackpanel>
<textblock Text="A"></textblock>
</stackpanel>
问题同上
谢谢!
以编程方式:
textBlock1.Background = new SolidColorBrush(Colors.Yellow);
在XAML中:
<TextBlock Name="textBlock1">
<TextBlock.Background>
<SolidColorBrush Color="Yellow" />
</TextBlock.Background>
</TextBlock>
要在单击文本块时更改背景颜色,您应该使用带有触发器的自定义样式。这并不难,如果您将搜索或询问有关使用样式和触发器的信息。你绝对不应该在 XAML 设计模式中为此使用 C#。
使用 EventTrigger 和 Color Animation 您可以在 MouseDown 上更改 TextBlock 背景颜色或 MouseLeave
xaml代码
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseDown">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Yellow" To="Blue" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Blue" To="Yellow" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBlock Text="A" Background="Yellow"></TextBlock>
<TextBlock Text="B" Background="Yellow"></TextBlock>
</StackPanel>
更新
使用 TextBox with 属性 IsReadOnly=True 而不是文本块。
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="Yellow"></Setter>
<Setter Property="BorderThickness" Value="0"></Setter>
<Setter Property="IsReadOnly" Value="True"></Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="TextBox.GotFocus">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Yellow" To="Blue" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="TextBox.LostFocus">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" From="Blue" To="Yellow" Duration="0:0:0.1"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<TextBox Text="A"></TextBox>
<TextBox Text="A"></TextBox>
</StackPanel>
<TextBlock Text="Hello, styled world!" FontSize="28" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Background" Value="Yellow"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Blue" />
<Setter Property="TextDecorations" Value="Underline" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
这很可能是您问题的解决方案。正如我指出的那样,由于您希望一个控件依赖于其他控件的各种要求的性质,因此无法实现仅 xaml 的解决方案。
你当然可以 fiddle 处理其余部分。
public class RadioTextblock : TextBlock
{
static RadioTextblock()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(RadioTextblock), new FrameworkPropertyMetadata(typeof(RadioTextblock)));
}
public static readonly DependencyProperty GroupProperty = DependencyProperty.Register(
"Group", typeof (string), typeof (RadioTextblock), new PropertyMetadata(string.Empty));
public string Group
{
get { return (string) GetValue(GroupProperty); }
set { SetValue(GroupProperty, value); }
}
public static readonly DependencyProperty ActiveColorProperty = DependencyProperty.Register(
"ActiveColor", typeof (Brush), typeof (RadioTextblock), new PropertyMetadata(default(Brush)));
public Brush ActiveColor
{
get { return (Brush) GetValue(ActiveColorProperty); }
set { SetValue(ActiveColorProperty, value); }
}
public static readonly DependencyProperty RestorationColorProperty = DependencyProperty.Register(
"RestorationColor", typeof (Brush), typeof (RadioTextblock), new PropertyMetadata(default(Brush)));
public Brush RestorationColor
{
get { return (Brush) GetValue(RestorationColorProperty); }
set { SetValue(RestorationColorProperty, value); }
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
// there may be a better hook for this. but i'm not writing custom controls that often. anything after styles are applied should be good
RestorationColor = Background;
}
protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
{
RestoreOtherBackgrounds(this);
base.OnPreviewMouseDown(e);
}
private void RestoreOtherBackgrounds(RadioTextblock radioTextblock)
{
var topParent = GetTopMostParent(radioTextblock);
var controlsWithGroup = GetChildrenRecursive<RadioTextblock>(topParent).ToLookup(d => (string)d.GetValue(GroupProperty));
var similar = controlsWithGroup[radioTextblock.Group];
foreach (var match in similar)
{
if (match == radioTextblock)
{
match.Background = ActiveColor;
}
else
{
match.Background = match.RestorationColor;
}
}
}
private DependencyObject GetTopMostParent(RadioTextblock radioTextblock)
{
DependencyObject current = radioTextblock;
while (current != null)
{
var cParent = VisualTreeHelper.GetParent(current);
if (cParent == null || cParent == current)
break;
current = cParent;
}
return current;
}
private IEnumerable<T> GetChildrenRecursive<T>(DependencyObject current) where T : DependencyObject
{
T casted;
var childCount = VisualTreeHelper.GetChildrenCount(current);
for (int i = 0; i < childCount; i++)
{
var currentChild = VisualTreeHelper.GetChild(current, i);
casted = currentChild as T;
if(casted != null)
yield return casted;
foreach (var subChild in GetChildrenRecursive<T>(currentChild))
{
if (subChild != null)
yield return casted;
}
}
}
}
改变你的XAML
结构如下
xmlns:local="clr-namespace:your_assembly_Name"
.....
<StackPanel>
<StackPanel.Resources>
<local:BackgroundConverter x:Key="backgroundConverter"/>
<Style TargetType="TextBlock">
<EventSetter Event="MouseDown" Handler="TextBlockMouseDownEvent" />
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource backgroundConverter}">
<Binding Path="Name" RelativeSource="{RelativeSource Self}"/>
<Binding Path="SelectedTextBlockName"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<TextBlock x:Name="text1" Text="Header"/>
<TextBlock x:Name="text2" Text="Header"/>
<TextBlock x:Name="text3" Text="Header"/>
<TextBlock x:Name="text4" Text="Header"/>
</StackPanel>
使用以下 IMultiValueConverter
并在您的代码后面添加 TextBlockMouseDownEvent
事件处理程序和一个 DependencyProperty
。
////DependencyProperty
public string SelectedTextBlockName
{
get { return (string)GetValue(SelectedTextBlockNameProperty); }
set { SetValue(SelectedTextBlockNameProperty, value); }
}
// Using a DependencyProperty as the backing store for SelectedTextBlock. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedTextBlockNameProperty =
DependencyProperty.Register("SelectedTextBlockName", typeof(string), typeof(Class_Name), new PropertyMetadata(null));
.......
private void TextBlockMouseDownEvent(object sender, MouseButtonEventArgs e)
{
TextBlock txtBlock = sender as TextBlock;
if (txtBlock != null)
{
SelectedTextBlockName = txtBlock.Name;
}
}
.......
public class BackgroundConverter : IMultiValueConverter
{
/// <summary>
/// Values[0] = Name of TextBlock
/// values[1] = SelectedTextBlockName
/// If matches then it is selected
/// </summary>
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values[0] != null && values[1] != null && values[0].ToString() == values[1].ToString())
return new SolidColorBrush(Colors.Blue);
return new SolidColorBrush(Colors.White);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
如果您想设置默认的 SelectedTextBlock,那么只需设置您想要作为默认选择的 TextBlock 名称。 像这样:
SelectedTextBlockName = "text1";