WPF遍历界面控件

需求是这样的,系统要监测风,雨,雪多个自然灾害。在界面上有这些灾害突发的报警框。本来报警框的背景是由于级别不同显示不同的颜色,但是现在发现,当报警背景为蓝色是,黑色字体 看不出来。又由于技术文档上规定背景颜色了,所以现在只能改变所有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属性,如果遍历对象是GridStackPanl那么是可以实现,但只能遍历当前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只有界面和后台两个进程,导致现在由于前台处理的数据比较多,界面也用到大量的委托 比较慢,目前还不知有有什么解决的办法,都在研究中。


    知识的相通性体会很深~

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值