需求是这样的,系统要监测风,雨,雪多个自然灾害。在界面上有这些灾害突发的报警框。本来报警框的背景是由于级别不同显示不同的颜色,但是现在发现,当报警背景为蓝色是,黑色字体 看不出来。又由于技术文档上规定背景颜色了,所以现在只能改变所有lbl的字体。而这些控件都是WPF自定义控件的一些 元素。
要实现这个功能,有很多种方式。WPF的好处 就是既可以像Html+CSS 去设置, 也可以像Winform一样去更改。重点说一下解决方式。
这个功能要调用的有大概10多处,每个窗体有6个左右lbl,所以每次给每个控件挨个赋值是绝对不能用的。
先看一下样式和自定义控件代码。
样式:
<span style="font-family:KaiTi_GB2312;"> <UserControl x:Class="ICT.RCS.Modules.SingleLine.Facilities.UserControlFile.ucSnowAlert" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="150" d:DesignWidth="340" BorderThickness="1" BorderBrush="#AAAAAA"> <Grid x:Name="grdSnowAlert" Height="150"> <Grid.Resources > <Style TargetType="Label" > <Setter Property="FontSize" Value="12"/> <Setter Property="Foreground" Value="{Binding FontColorBrush,UpdateSourceTrigger=PropertyChanged}"/> <Setter Property="Background" Value="{Binding FontColorBrush,UpdateSourceTrigger=PropertyChanged}"/> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="VerticalAlignment" Value="Center"></Setter> <Setter Property="FontFamily" Value="Microsoft YaHei"/> </Style> </Grid.Resources> <Grid.RowDefinitions> <RowDefinition Height=" 30" ></RowDefinition> <RowDefinition Height=" 30" ></RowDefinition> <RowDefinition Height=" 30" ></RowDefinition> <RowDefinition Height=" 30"></RowDefinition> <RowDefinition Height=" 30"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="60*"></ColumnDefinition> <ColumnDefinition Width="100*"></ColumnDefinition> <ColumnDefinition Width="60*"></ColumnDefinition> <ColumnDefinition Width="120*"></ColumnDefinition> </Grid.ColumnDefinitions> <Label Content="雪 深 报 警" Width="322" HorizontalAlignment="Center" FontWeight="Bold" Grid.ColumnSpan="4" Margin="0,4,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Height="27"/> <Border Grid.Column="0" BorderThickness="0,1,1,1" BorderBrush="#AEAEAE" Grid.Row="1" > <Label Content="监测点" HorizontalAlignment="Center" Margin="5,-2,5,2"/> </Border> <Border Grid.Row=" 1" Grid.Column=" 2" BorderBrush="#AEAEAE" BorderThickness="1"> <Label Content="报警时间" HorizontalAlignment="Center" /> </Border> <Border Grid.Row=" 2" Grid.Column="0" BorderBrush="#AEAEAE" BorderThickness="0,0,1,1"> <Label Content="影响区间" HorizontalAlignment="Center" /> </Border> <Border Grid.Row=" 3" Grid.Column=" 0" BorderBrush="#AEAEAE" BorderThickness ="0,0,1,1"> <Label Content="限速区段" HorizontalAlignment="Center" Margin="0,-1,0,1"/> </Border> <Border Grid.Column="1" BorderBrush="#AEAEAE" BorderThickness ="0,1,0,1" Grid.Row="1"> <Label x:Name="lblSnowCheckPoint" Content="" Margin="0,0,-1,0" Width="100" /> </Border> <Border Grid.Row="1" Grid.Column=" 3" BorderBrush="#AEAEAE" BorderThickness ="0,1,0,1"> <Label x:Name="lblSnowAlarmTime" Content="" Margin="0,-1,0,1"/> </Border> <Border Grid.Row=" 2" Grid.Column=" 1" Grid.ColumnSpan=" 3" BorderBrush="#AEAEAE" BorderThickness ="0,0,0,1"> <Label x:Name="lblSnowEffectArea" Content="" /> </Border> <Border Grid.Row=" 3" Grid.Column=" 1" BorderBrush="#AEAEAE" BorderThickness ="0,0,0,1"> <Label x:Name="lblSnowLockArea" Content="" /> </Border> <Border Grid.Row=" 3" Grid.Column=" 2" BorderBrush="#AEAEAE" BorderThickness="1,0,1,1"> <Label Content="处置措施" HorizontalAlignment="Center" Foreground="Black"/> </Border> <Border Grid.Row="3" Grid.Column=" 3" BorderBrush="#AEAEAE" BorderThickness ="0,0,0,1"> <Label x:Name="lblSnowCommand" Content="" /> </Border> <Button x:Name="btnAlert" Grid.ColumnSpan="4" Content="报 警 确 认" Grid.Column="0" HorizontalAlignment="Center" Height="20" Grid.Row="4" VerticalAlignment="Center" Width="75" Margin="0" Click="Button_Click" IsEnabled="False"/> </Grid> </UserControl> </span>
现在界面是这样的。
解决方案:
我采用的通过判断控件的属性来赋值。这和vb是相通的,只不过需要属性一下 几个控件都有哪些属性。谁有什么节点等。
<span style="font-family:KaiTi_GB2312;">using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ChildDemo { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : UserControl { private SolidColorBrush sBush = new SolidColorBrush(); public MainWindow() { InitializeComponent(); this.ChangeLblColor(this.grdRainAlert.Children, 2); } #region 根据警报状态更改报警框中字体颜色--2015-7-31 /// <summary> /// 根据警报状态更改报警框中字体颜色 /// </summary> /// <param name="uiControls">Gride(报警框)的子节点</param> /// <param name="alermStatus">报警状态</param> public void ChangeLblColor(UIElementCollection uiControls, int alermStatus) { if (uiControls != null) //遍历每个级别的控件,当控件类型为lbl 并且状态为2时,改变字体颜色为白。 foreach (UIElement element in uiControls) { if (element is Label) switch (alermStatus) { case 2: (element as Label).Foreground = new SolidColorBrush(Colors.White); break; default: (element as Label).Foreground = new SolidColorBrush(Colors.Black); break; } else if (element is Border && (element as Border).Child is Label) //如果该控件为border,border的子节点是lbl { Label lbl = (Label)(element as Border).Child; switch (alermStatus) { case 2: lbl.Foreground = new SolidColorBrush(Colors.White); break; default: lbl.Foreground = new SolidColorBrush(Colors.Black); break; } } } return; } #endregion } } </span>
以上是一种应用。这个方法如果针对其他情况还不是很好用,其实还可以抽象出一个万能方法。
正好总结的时候浏览到 一篇这样的博客。觉得总结的很详细。 拿出来分享一下~
------------------------------------------------------------------------------以下为摘抄---------------------------------------------------
c#winform中遍历控件,界面具有Controls属性,可以直接进行遍历访问:
<span style="font-family:KaiTi_GB2312;">在百度上看到很多人采用: foreach (UIElement element in this.Control.Children) { if (element is UserControl) { UserControl current = ((UserControl)element); } }</span>
但是,通过使用,可以发现其中的问题:
不是每一个Control都具有Children属性,如果遍历对象是Grid、StackPanl那么是可以实现,但只能遍历当前Grid的子控件,对当前控件的子控件中的子控件则无法实现遍历,如
<span style="font-family:KaiTi_GB2312;"><grid name ="Parent"> <grid name ="son"/> <grid name ="son2"> <grid name = "son3"/> </grid> </grid> </span>
则只能遍历到son和son2,对son3束手无策,递归是吧? 在这个小例子中,递归ok,但若是下面的呢?
<span style="font-family:KaiTi_GB2312;"> <grid name ="Parent"> <grid name ="son"/> <grid name ="son2"> <StackPanl name = "panl"/> <grid name ="son3"/> </StackPanl > </grid></span>
StackPanl不具有children属性,因此你无法对其进行遍历。
但是问题仍然可以进行解决:
重点来了:
<span style="font-family:KaiTi_GB2312;"> /// <summary> /// 功 能:遍历界面所有TextBox,设置IsEnable属性为False /// 作 者:Liu Hao | 日期:2012年5月30日 /// </summary> /// <param name="uiControls"></param> private void SetNotEditable(UIElementCollection uiControls) { foreach (UIElement element in uiControls) { if (element is TextBox) { (element as TextBox).IsEnabled = false; } else if (element is Grid) { this.SetNotEditable((element as Grid).Children); } else if (element is Expander) { //此代码仅供参考 //在您的布局中,Expander或者其他不具有Children属性的控件的Content,若不是StackPanl或Grid,而是其他的子控件,则需要更多的判断 if ((element as Expander).Content is StackPanel) { StackPanel sa = (element as Expander).Content as StackPanel; this.SetNotEditable(sa.Children); } else if ((element as Expander).Content is Grid) { Grid sa = (element as Expander).Content as Grid; this.SetNotEditable(sa.Children); } } else if (element is StackPanel) { this.SetNotEditable((element as StackPanel).Children); } else if (element is ScrollViewer) { StackPanel sp = (element as ScrollViewer).Content as StackPanel; this.SetNotEditable(sp.Children); //ScrollViewer不具有Children属性,无法对其进行遍历,但是具有Content属性,作为容器型控件,一般都可以通过这样的方法来解决。 } } } //在事件中进行调用 private void btnQuery_Click(object sender, RoutedEventArgs e) { this.SetNotEditable(this.gridUCContent.Children); //gridUCContent为最顶层Grid } </span>
此代码及讲解仅作为参考,代码主要针对上面我自己的Xaml中的布局。不能直接粘贴引用,但可以提供思路。
-------------------------------------------------------------------------------------------
这是一种类似Winform的实现方式,最近在研究WPF的画刷和绑定,目测通过这种方式也能实现。 最初自己以为WPF就是简单的拖拽控件,现在发现如果只会简单的拖拽控件,是连一个最基本的简单的小系统都无法完成。它相当于既有Winform的拖拽性质,也有BS的网页制作的性质。而且界面能做出很炫很精确的效果,目前还在 研究。当然也有一个弊端就是WPF只有界面和后台两个进程,导致现在由于前台处理的数据比较多,界面也用到大量的委托
比较慢,目前还不知有有什么解决的办法,都在研究中。
知识的相通性体会很深~
版权声明:本文为博主原创文章,未经博主允许不得转载。