我正在开发一个包含多个选项卡的程序,每个选项卡包含多个按钮,单击这些按钮时会在BackgroundWorker对象中执行SQL调用。单击按钮后,只要SQL进程正在运行,其他按钮就会被禁用
因为其中一些SQL调用可能需要一个多小时,所以我使用BackgroundWorker,以便GUI仍然响应用户输入(即更改选项卡),但按钮被禁用,直到当前SQL进程完成。
其中一项功能请求是将当前所选选项卡标题字体的颜色更改为绿色(通常为黑色),以指示此选项卡中的一个按钮是启动当前正在运行的SQL的按钮。一旦SQL完成,字体颜色应该返回黑色。
是否可以使用style / datatrigger执行此操作?按下按钮后,我无法想到将样式应用于当前选定的选项卡的方法,如果我在后台工作人员仍在工作时切换选项卡,则保持该着色。
我对此的另一种想法是,每当我单击一个按钮然后在后台工作程序完成后将其更改回来时,通过代码更改选项卡标题字体颜色的方法,但这需要更新所有ButtonClicked()方法。 / p>
我也对任何其他解决方案持开放态度。
我知道async / await功能但不能更改使用BackgroundWorker执行SQL的代码,所以请不要使用async / await建议。
答案 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
。