[英]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.