wpf 如何更改文本块背景?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27792007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:49:37  来源:igfitidea点击:

How to change textblock background?

c#wpfxamltextblock

提问by GSP

This is my xaml structure

这是我的 xaml structure

<stackpanel>
  <textblock Text="A"></textblock>
  <textblock Text="B"></textblock>
</stackpanel>

Stackpanel, It can loop to generate more same structures.

Stackpanel, 它可以循环生成更多相同的结构。

How can I change background color of texblock when I click it?

单击时如何更改 texblock 的背景颜色?

UPDATE: I just want change on xaml file not using C#.

更新I just want change on xaml file not using C#.

Default I has yellow, but when I click a textblock, Its background will change to Blue.

默认我有黄色,但是当我点击一个文本块时,它的背景会变成蓝色。

UPDATE 2: If click A, A will change to blue until I click another.

更新 2:如果单击 A,A 将变为蓝色,直到我单击另一个。

Detail:

细节:

  1. I click A(A is yellow), A will change to be blue ==> A is blue

  2. I click B(B is yellow and A is blue), B will change to be blue and A will change to be yellow.

  1. 我点击 A (A is yellow), A 会变成蓝色 ==> A 是蓝色

  2. 我点击 B (B is yellow and A is blue), B 会变成蓝色, A 会变成黄色。

UPDATE 3: How about this?

更新 3:这个怎么样?

<stackpanel>
      <textblock Text="A"></textblock>
</stackpanel>

<stackpanel>
      <textblock Text="A"></textblock>
</stackpanel>
<stackpanel>
      <textblock Text="A"></textblock>
</stackpanel>

The question is same above

上面的问题是一样的

Thanks!

谢谢!

采纳答案by Heena Patil

Using EventTriggerand Color Animationyou can change color of TextBlock Background color on MouseDownor MouseLeave

使用EventTriggerColor Animation,您可以更改MouseDownMouseLeave上 TextBlock 背景颜色的颜色



xaml code

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>


Update

更新

Use TextBox with property IsReadOnly=Trueinstead of textblock.

使用带有属性 IsReadOnly=True 的 TextBox而不是 textblock。

    <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>

回答by Croll

Programmatically:

以编程方式:

textBlock1.Background = new SolidColorBrush(Colors.Yellow);

In XAML:

在 XAML 中:

<TextBlock Name="textBlock1">
    <TextBlock.Background>
        <SolidColorBrush Color="Yellow" />
    </TextBlock.Background>
</TextBlock>

To change background color when you click on a textBlock, you should use custom style with triggers. This is not hard, if you will search or ask about using styles and triggers. You definetely should not use C# for this in XAML design patterns.

要在单击 textBlock 时更改背景颜色,您应该使用带有触发器的自定义样式。如果您要搜索或询问使用样式和触发器,这并不难。您绝对不应在 XAML 设计模式中为此使用 C#。

回答by Dhru 'soni

  <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>

回答by Dbl

This willbe the solution for your problem most likely. As i pointed out a xaml only solution won't be possible due to the nature of your requirement that you want one control to be dependent on a varierty of other controls.

这将是您的问题最有可能的解决方案。正如我所指出的,由于您的要求的性质,您希望一个控件依赖于各种其他控件,因此无法使用仅 xaml 的解决方案。

You can fiddle around with the rest of it of course.

当然,您可以摆弄其余部分。

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;
            }
        }
    }
}

回答by Amol Bavannavar

Change your XAMLstructure as follow's

改变你的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>

Use following IMultiValueConverterand Add TextBlockMouseDownEventEvent Handler as well as One DependencyPropertyin your code behind.

在后面的代码中使用以下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();
    }
}

If you want to set default SelectedTextBlock then just set the TextBlock name which you want as a default to be selected. like this :

如果您想设置默认的 SelectedTextBlock,那么只需设置您希望作为默认选择的 TextBlock 名称。像这样 :

SelectedTextBlockName = "text1";