繁体   English   中英

WPF:按下按钮时更改选项卡页眉字体颜色

[英]WPF: Change Tab Header Font Color When Button is Pressed

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

因为其中一些SQL调用可能需要一个小时以上的时间,所以我正在使用BackgroundWorker,以便GUI仍会响应用户输入(即,更改选项卡),但是在当前SQL进程完成之前,按钮一直处于禁用状态。

功能请求之一是将当前选定选项卡的标题字体的颜色更改为绿色(通常为黑色),以指示该选项卡中的按钮之一是启动当前运行的SQL的按钮。 SQL完成后,字体颜色应恢复为黑色。

是否可以使用样式/数据触发来做到这一点? 我想不出一种方法,可以在按下按钮后将样式应用于当前选定的选项卡,然后在后台工作人员仍在工作时切换选项卡时保持该颜色不变。

我对此的其他想法是,只要我单击一个按钮,就可以通过代码更改选项卡标题字体的颜色,然后在后台工作人员完成操作后将其更改回该方法,但这将需要更新所有ButtonClicked()方法。

我也欢迎其他解决方案。

我了解异步/等待功能,但是无法更改使用BackgroundWorker执行SQL的代码,因此请不要提出使用异步/等待的建议。

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

public bool IsRunning { get; set; }

使用Converter将背景色绑定到background属性。 http://wpftutorial.net/ValueConverters.html

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

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

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

<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属性更改。

试试看

<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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM