WPF:按下按钮时更改选项卡标题字体颜色

时间:2015-01-21 19:46:33

标签: c# wpf styles datatrigger tabitem

我正在开发一个包含多个选项卡的程序,每个选项卡包含多个按钮,单击这些按钮时会在BackgroundWorker对象中执行SQL调用。单击按钮后,只要SQL进程正在运行,其他按钮就会被禁用

因为其中一些SQL调用可能需要一个多小时,所以我使用BackgroundWorker,以便GUI仍然响应用户输入(即更改选项卡),但按钮被禁用,直到当前SQL进程完成。

其中一项功能请求是将当前所选选项卡标题字体的颜色更改为绿色(通常为黑色),以指示此选项卡中的一个按钮是启动当前正在运行的SQL的按钮。一旦SQL完成,字体颜色应该返回黑色。

是否可以使用style / datatrigger执行此操作?按下按钮后,我无法想到将样式应用于当前选定的选项卡的方法,如果我在后台工作人员仍在工作时切换选项卡,则保持该着色。

我对此的另一种想法是,每当我单击一个按钮然后在后台工作程序完成后将其更改回来时,通过代码更改选项卡标题字体颜色的方法,但这需要更新所有ButtonClicked()方法。 / p>

我也对任何其他解决方案持开放态度。

我知道async / await功能但不能更改使用BackgroundWorker执行SQL的代码,所以请不要使用async / await建议。

3 个答案:

答案 0 :(得分:0)

绑定到选项卡的ViewModel实例可能具有名为running的属性。

public bool IsRunning { get; set; }

使用转换器将背景颜色绑定到背景属性。 http://wpftutorial.net/ValueConverters.html

取决于true / false,转换器将返回颜色。您甚至可以将颜色作为参数传递给绑定。 在执行查询以将其设置为true之前,一旦完成将其设置为true。

myVM.IsRunning=true;
executeQuery();
myVM.IsRunning=false;

答案 1 :(得分:0)

这样的事情应该是你想要的:

<TabControl ItemsSource="{Binding Tabs}">

    <TabControl.ItemTemplate>
        <DataTemplate>

            <TextBlock Text="{Binding TabHeader}">
                <TextBlock.Style>
                    <Style TargetType="TextBlock">

                        <Setter Property="Foreground" Value="Black"/>

                        <Style.Triggers>
                            <DataTrigger Binding="{Binding IsWorking}" Value="True">

                                <Setter Property="Foreground" Value="Green"/>

                            </DataTrigger>
                        </Style.Triggers>

                    </Style>
                </TextBlock.Style>
            </TextBlock>

        </DataTemplate>
    </TabControl.ItemTemplate>

</TabControl>

Tabs集合中每个项目的视图模型如下所示:

public class TabViewModel
{
    public string TabHeader { get; set; }
    public bool IsWorking { get; set; }
}

显然,视图模型应该实现notify属性的更改。

答案 2 :(得分:0)

尝试

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Background="LightGray" 
    Title="Window1" Height="350" Width="700" >
    <Window.Resources>
        <Style x:Key="myHeaderStyle" TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=DataContext}" Value="True">
                    <Setter Property="Foreground" Value="Green" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <DataTemplate x:Key="myHeader">
            <TextBlock Text="{Binding}" Style="{DynamicResource myHeaderStyle}" />
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <TabControl>
            <TabItem x:Name="FirstTab" Header="First tab" HeaderTemplate="{DynamicResource myHeader}" DataContext="{Binding FirstTabSelected}">
                <Button Click="Button_Click">
                    First button
                </Button>
            </TabItem>
            <TabItem Header="Second tab" HeaderTemplate="{DynamicResource myHeader}"  DataContext="{Binding SecondTabSelected}">
                <Button Click="Button_Click_1">
                    Second button
                </Button>
            </TabItem>
        </TabControl>
    </Grid>
</Window>

背后的代码

[ImplementPropertyChanged]
public partial class MainWindow : Window
{
    public bool FirstTabSelected { get; set; }
    public bool SecondTabSelected { get; set; }

    public MainWindow()
    {
        FirstTabSelected = true;
        SecondTabSelected = true;
        InitializeComponent();

        this.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        FirstTabSelected = !FirstTabSelected;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        SecondTabSelected = !SecondTabSelected;
    }
}

我正在使用Fody propertyChanged,因此我无需手动实施INotifyPropertyChanged