• 用Silverlight打造位运算器(3)--完成


          上一回我们说到,使用模板制作的SpeedButton无法在载入浏览器时处于按下状态,这个缺点是我无法忍受的,没办法,只好使用用户控件的方式重写SpeedButton以解决这个问题。所有控件完成后,位移运算器就变得十分简单了。没想到当年要3000行代码完成的东西,变得如此简单,有些超出我的预期。
    好,先看看位移运算器的完整效果,请首先安装Silverlight3.0
    最新发现不登录博客园的用户无法直接看到Silverlight,如果是这样,请移步到以下网址观看动画:

    http://www.bbniu.com/matrix/ShowApplication.aspx?id=147



         界面做成这样,主要是考虑到可以用它来上课做演示,很多计算机课程都需要讲到位运算。
    制作步骤:
    一、 重写SpeedButton
    1、 在BitLibrary中删除Theme文件夹及SpeedButton.cs文件。
    2、 在【BitLibrary】项目上单击鼠标右键,选择【添加】【新建项】,添加一个Silverlight用户控件,并命名为“SpeedButton.xaml”。更改SpeedButton.xaml文件如下:

    <UserControl x:Class="BitLibrary.SpeedButton"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml">
        
    <UserControl.Resources>
            
    <LinearGradientBrush x:Key="BorderNormalBrush">
                
    <GradientStop Color="#FFA3AEB9" Offset="0"/>
                
    <GradientStop Color="#FF8399A9" Offset="0.375"/>
                
    <GradientStop Color="#FF718597" Offset="0.375"/>
                
    <GradientStop Color="#FF617584" Offset="1"/>
            
    </LinearGradientBrush>
            
    <SolidColorBrush x:Key="BorderBgPressedBrush" Color="#FF6DBDD1"/>
            
    <SolidColorBrush x:Key="BorderBgNormaldBrush" Color="White"/>
            
    <LinearGradientBrush x:Key="RectNormalBrush" StartPoint=".7,0" EndPoint=".7,1">
                
    <GradientStop Color="#FFFFFFFF" Offset="0" />
                
    <GradientStop Color="#F1FFFFFF" Offset="0.375" />
                
    <GradientStop Color="#DCFFFFFF" Offset="0.625" />
                
    <GradientStop Color="#8FFFFFFF" Offset="1" />
            
    </LinearGradientBrush>
            
    <LinearGradientBrush x:Key="RectMouseOverBrush" StartPoint=".7,0" EndPoint=".7,1">
                
    <GradientStop Color="#FFFFFFFF" Offset="0" />
                
    <GradientStop Color="#C2FFFFFF" Offset="0.375" />
                
    <GradientStop Color="#8CFFFFFF" Offset="0.625" />
                
    <GradientStop Color="#C8FFFFFF" Offset="1" />
            
    </LinearGradientBrush>
            
    <LinearGradientBrush x:Key="RectPressedBrush" StartPoint=".7,0" EndPoint=".7,1">
                
    <GradientStop Color="#D8FFFFFF" Offset="0" />
                
    <GradientStop Color="#C6FFFFFF" Offset="0.375" />
                
    <GradientStop Color="#8CFFFFFF" Offset="0.625" />
                
    <GradientStop Color="#3FFFFFFF" Offset="1" />
            
    </LinearGradientBrush>
        
    </UserControl.Resources>
        
    <Grid x:Name="LayoutRoot" Background="Transparent" Width="30" Height="30">
            
    <Border x:Name="Bd" CornerRadius="3" Background="{StaticResource BorderBgNormaldBrush}" BorderThickness="1" 
                BorderBrush
    ="{StaticResource BorderNormalBrush}">
                
    <Grid Background="Transparent" Margin="1">
                    
    <Border x:Name="BackgroundAnimation" Background="#FF448DCA"/>
                    
    <Rectangle x:Name="BackgroundGradient" Fill="{StaticResource RectNormalBrush}"/>
                
    </Grid>
            
    </Border>
            
    <ContentPresenter x:Name="contentPresenter" VerticalAlignment="Center"
                              HorizontalAlignment
    ="Center" Margin="0"/>
        
    </Grid>
    </UserControl>

          在这个SpeedButton里使用了跟之前模板里一样的外观,不同之处是在控件的资源内添加了6种画刷,这些静态资源不但可以直接在xaml文件中使用StaticResource关键字进行引用,也可以在cs文件中使用this. Resources["资源名称"]进行引用,从而可以很方便地改变控件外观。
    3、 打开SpeedButton.xaml.cs文件,更改代码如下:

     1 public partial class SpeedButton : UserControl
     2     {
     3         public SpeedButton()
     4         {
     5             InitializeComponent();
     6             this.MouseEnter += new MouseEventHandler(SpeedButton_MouseEnter);
     7             this.MouseLeave += new MouseEventHandler(SpeedButton_MouseLeave);
     8             this.MouseLeftButtonDown += new MouseButtonEventHandler(SpeedButton_MouseLeftButtonDown);
     9         }
    10         //声明依赖属性Text
    11         public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
    12             "Text"typeof(string), typeof(SpeedButton), null);
    13         public string Text
    14         {
    15             get { return (string)contentPresenter.Content; }
    16             set { contentPresenter.Content = value; }
    17         }
    18         public SystemState State
    19         {
    20             get;
    21             set;
    22         }
    23         private Boolean isPress = false//指示按钮是否处于按下状态
    24         public Boolean IsPress
    25         {
    26             get
    27             {
    28                 return isPress;
    29             }
    30             set
    31             {
    32                 if (IsPress == value) return;
    33                 isPress = value;
    34                 if (isPress)
    35                 {
    36                     Bd.Background = (SolidColorBrush)Resources["BorderBgPressedBrush"];
    37                     BackgroundGradient.Fill = (LinearGradientBrush)Resources["RectPressedBrush"];
    38                 }
    39                 else
    40                 {
    41                     Bd.Background = (SolidColorBrush)Resources["BorderBgNormaldBrush"];
    42                     BackgroundGradient.Fill = (LinearGradientBrush)Resources["RectNormalBrush"]; 
    43                 }
    44             }
    45         }
    46         void SpeedButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    47         {
    48             if (!isPress)
    49             {
    50                 IsPress = true;
    51             }
    52         }
    53 
    54         void SpeedButton_MouseLeave(object sender, MouseEventArgs e)
    55         {
    56             if (!isPress)
    57             {
    58                 BackgroundGradient.Fill = (LinearGradientBrush)Resources["RectNormalBrush"];
    59             }
    60         }
    61 
    62         void SpeedButton_MouseEnter(object sender, MouseEventArgs e)
    63         {
    64             if (!isPress)
    65             {
    66                 BackgroundGradient.Fill = (LinearGradientBrush)Resources["RectMouseOverBrush"];
    67             }
    68         }
    69 }

    大家应该也会注意到,之前在模板中,外观的改变使用的是动画,但所有的动画时间(Duration)都为0。而在现在这个SpeedButton控件中,通过直接更改画刷来改变控件外观,这些更改都是在鼠标事件中实现的。虽然实现不同,但效果是一样的。运行程序,我们发现OCT按钮是处于按下状态的。终于解决了这个大bug。
    大家可以对比相同控件两种不同的做法,使用模板控件从ContentControl控件继承,而使用用户控件需要从UserControl进行继承,这样很多放在UserControl里的控件的属性就会被屏敝掉,从而不能再调用Content属性对按钮上显示的文字进行设置。如本例所示,声明了一个依赖属性Text来对按钮上的文字进行设置。
    经过以上努力,终于可以开始写位移运算器了,当然,没遇到任何困难,如砍瓜切菜般,迅速完成。唯一不爽的地方是VS2008里使用SL3没有界面设计窗口,要不停地运行程序来看控件位置,有点郁闷。

     二、位运算器主程序
    1、更改MainPage.xaml代码如下:

    <UserControl x:Class="BitCalculator.MainPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d
    ="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        xmlns:src
    ="clr-namespace:BitLibrary;assembly=BitLibrary"
        mc:Ignorable
    ="d" d:DesignWidth="569" d:DesignHeight="195">
        
    <Canvas x:Name="LayoutRoot" Background="SkyBlue" Loaded="LayoutRoot_Loaded">
            
    <src:ToolBar x:Name="tbTop" Grid.Row="1" SelectionChange="tb_SelectionChange"
                         Canvas.Left
    ="10" Canvas.Top="17"/>
            
    <src:BitTextBox x:Name="btxtTop" Text="20091122" Canvas.Left="132" Canvas.Top="0"/>
            
    <Button x:Name="btnTopSHL" Content="&lt;&lt;" Canvas.Left="469" Canvas.Top="17" Width="30" Height="30" ToolTipService.ToolTip="左移" Click="SHL_Click" />
            
    <Button x:Name="btnTopSHR" Content=">>" Canvas.Left="499" Canvas.Top="17" Width="30" Height="30" ToolTipService.ToolTip="右移" Click="SHR_Click"/>
            
    <Button x:Name="btnTopNOT" Content="~" Canvas.Left="529" Canvas.Top="17" Width="30" Height="30" ToolTipService.ToolTip="求补" Click="NOT_Click"/>

            
    <src:ToolBar x:Name="tbMid" Grid.Row="1" SelectionChange="tb_SelectionChange"
                         Canvas.Left
    ="10" Canvas.Top="49"/>
            
    <src:BitTextBox x:Name="btxtMid" Text="20091122" Canvas.Left="132" Canvas.Top="32"/>
            
    <Button x:Name="btnMidSHL" Content="&lt;&lt;" Canvas.Left="469" Canvas.Top="49" Width="30" Height="30" ToolTipService.ToolTip="左移" Click="SHL_Click"/>
            
    <Button x:Name="btnMidSHR" Content=">>" Canvas.Left="499" Canvas.Top="49" Width="30" Height="30" ToolTipService.ToolTip="右移" Click="SHR_Click"/>
            
    <Button x:Name="btnMidNOT" Content="~" Canvas.Left="529" Canvas.Top="49" Width="30" Height="30" ToolTipService.ToolTip="求补" Click="NOT_Click"/>

            
    <Button x:Name="btnAnd" Content="AND" Canvas.Left="235" Canvas.Top="81" Width="30" Height="30" ToolTipService.ToolTip="与运算" Click="btnAnd_Click"/>
            
    <Button x:Name="btnOr" Content="OR" Canvas.Left="265" Canvas.Top="81" Width="30" Height="30" ToolTipService.ToolTip="或运算" Click="btnOr_Click"/>
            
    <Button x:Name="btnXor" Content="XOR" Canvas.Left="295" Canvas.Top="81" Width="30" Height="30" ToolTipService.ToolTip="异或运算" Click="btnXor_Click"/>
            
    <Button x:Name="btnMod" Content="MOD" Canvas.Left="325" Canvas.Top="81" Width="30" Height="30" ToolTipService.ToolTip="取模" Click="btnMod_Click"/>
            
    <Button x:Name="btnClear" Content="CLR" Canvas.Left="355" Canvas.Top="81" Width="30" Height="30" ToolTipService.ToolTip="清空文框" Click="btnClear_Click"/>
            
            
    <src:ToolBar x:Name="tbBottom" Grid.Row="1" SelectionChange="tb_SelectionChange"
                         Canvas.Left
    ="10" Canvas.Top="113"/>
            
    <src:BitTextBox x:Name="btxtBottom" Text="20091122" Canvas.Left="132" Canvas.Top="96"/>
            
    <Button x:Name="btnBottomSHL" Content="&lt;&lt;" Canvas.Left="469" Canvas.Top="113" Width="30" Height="30" ToolTipService.ToolTip="左移" Click="SHL_Click"/>
            
    <Button x:Name="btnBottomSHR" Content=">>" Canvas.Left="499" Canvas.Top="113" Width="30" Height="30" ToolTipService.ToolTip="右移" Click="SHR_Click"/>
            
    <Button x:Name="btnBottomNOT" Content="~" Canvas.Left="529" Canvas.Top="113" Width="30" Height="30" ToolTipService.ToolTip="求补" Click="NOT_Click"/>
            
            
    <CheckBox x:Name="cbFillZero" Content="二进制数字不足32位补0" IsChecked="true"
                      Canvas.Left
    ="10" Canvas.Top="150" Click="cbFillZero_Click"/>
            
    <CheckBox x:Name="cbAllCtrl" Content="统一进制控制" IsChecked="false"
                      Canvas.Left
    ="165" Canvas.Top="150" Click="cbAllCtrl_Click"/>
            
    <TextBlock Text="http://www.cnblogs.com/abatei" Canvas.Top="168" Canvas.Left="10"/>
        
    </Canvas>
    </UserControl>

    2、打开MainPage.xaml.cs文件,更改代码如下:

      1 using BitLibrary;
      2 
      3 namespace BitCalculator
      4 {
      5     public partial class MainPage : UserControl
      6     {
      7         public MainPage()
      8         {
      9             InitializeComponent();
     10         }
     11 
     12 
     13         private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
     14         {
     15             tbTop.Tag = btxtTop;
     16             tbMid.Tag = btxtMid;
     17             tbBottom.Tag = btxtBottom;
     18             btnTopSHL.Tag = btxtTop;
     19             btnTopSHR.Tag = btxtTop;
     20             btnTopNOT.Tag = btxtTop;
     21             btnMidSHL.Tag = btxtMid;
     22             btnMidSHR.Tag = btxtMid;
     23             btnMidNOT.Tag = btxtMid;
     24             btnBottomSHL.Tag = btxtBottom;
     25             btnBottomSHR.Tag = btxtBottom;
     26             btnBottomNOT.Tag = btxtBottom;
     27         }
     28 
     29         private void cbFillZero_Click(object sender, RoutedEventArgs e)
     30         {
     31             btxtTop.FillZero = (bool)cbFillZero.IsChecked;
     32             btxtMid.FillZero = (bool)cbFillZero.IsChecked;
     33             btxtBottom.FillZero = (bool)cbFillZero.IsChecked;
     34         }
     35 
     36         private void tb_SelectionChange(object sender, RoutedEventArgs e)
     37         {
     38             SystemState state=((ToolBar)sender).ToolState;
     39             if ((bool)cbAllCtrl.IsChecked)
     40             {
     41                 btxtTop.State = state;
     42                 btxtMid.State = state;
     43                 btxtBottom.State = state;
     44             }
     45             else
     46             {
     47                 ((BitTextBox)((ToolBar)sender).Tag).State = state;
     48             }
     49         }
     50 
     51         private void SHL_Click(object sender, RoutedEventArgs e)
     52         {
     53             BitTextBox btxt = (BitTextBox)((Button)sender).Tag;
     54             btxt.Value = btxt.Value << 1;
     55         }
     56 
     57         private void SHR_Click(object sender, RoutedEventArgs e)
     58         {
     59             BitTextBox btxt = (BitTextBox)((Button)sender).Tag;
     60             btxt.Value = btxt.Value >> 1;
     61         }
     62 
     63         private void NOT_Click(object sender, RoutedEventArgs e)
     64         {
     65             BitTextBox btxt = (BitTextBox)((Button)sender).Tag;
     66             btxt.Value = ~btxt.Value;
     67         }
     68 
     69         private void btnAnd_Click(object sender, RoutedEventArgs e)
     70         {
     71             btxtBottom.Value = btxtTop.Value & btxtMid.Value;
     72         }
     73 
     74         private void btnOr_Click(object sender, RoutedEventArgs e)
     75         {
     76             btxtBottom.Value = btxtTop.Value | btxtMid.Value;
     77         }
     78 
     79         private void btnXor_Click(object sender, RoutedEventArgs e)
     80         {
     81             btxtBottom.Value = btxtTop.Value ^ btxtMid.Value;
     82         }
     83 
     84         private void btnMod_Click(object sender, RoutedEventArgs e)
     85         {
     86             btxtBottom.Value = btxtTop.Value % btxtMid.Value;
     87         }
     88 
     89         private void btnClear_Click(object sender, RoutedEventArgs e)
     90         {
     91             btxtTop.Clear();
     92             btxtMid.Clear();
     93             btxtBottom.Clear();
     94         }
     95 
     96         private void cbAllCtrl_Click(object sender, RoutedEventArgs e)
     97         {
     98             if ((bool)cbAllCtrl.IsChecked)
     99             {
    100                 tbTop.Visibility = Visibility.Collapsed;
    101                 btxtTop.State = tbMid.ToolState;
    102                 tbBottom.Visibility = Visibility.Collapsed;
    103                 btxtBottom.State = tbMid.ToolState;
    104             }
    105             else
    106             {
    107                 tbTop.Visibility = Visibility.Visible;
    108                 tbTop.ToolState = btxtTop.State;
    109                 tbBottom.Visibility = Visibility.Visible;
    110                 tbBottom.ToolState = btxtBottom.State;
    111             }
    112         }
    113     }
    114 }
          界面上的按钮虽然很多,但很多按钮的事件是共用的,使用按钮的Tag属性来存放所控制的按钮,这样点击相应按钮时,只需通过Tag属性找到所控制的编辑框即可。
          位运算器完成后,我马上把成果用在了其他地方,在之前做的Hashtable动态演示程序中加入了位运算编辑框,这样在选中一个结点时,可以通过这个编辑框查看结点哈希码的不同进制的数字。
          演示地址:http://www.cnblogs.com/abatei/archive/2009/06/23/1509790.html
  • 相关阅读:
    IIS文件大小限制
    XAMPP 配置多端口 多站点
    C# 复制文件和文件夹
    Windows下 Python 安装包的配置
    从数据库读取数据绑定到TreeView(内含设置样式,图片)
    异步请求数据简单例子
    Jmeter使用_StringFromFile函数需要添加编码方式
    利用Fitnesse和Jmeter实现接口性能测试
    简易覆盖率信息收集框架
    如何对遗留代码进行单元测试(scrumgathering听后感)
  • 原文地址:https://www.cnblogs.com/abatei/p/1611934.html
Copyright © 2020-2023  润新知