天天看點

WPF中使用VisualBrush的執行個體

本文實作一個名為“你來我往”的小程式,該程式管理着“張三”和“李四”兩位童鞋擁有的現金,一開始,兩人均擁有100美元的現金,随着将現金從其中一人轉移至另外一人,兩人擁有的現金數在不斷變化,程式可以跟蹤這種變化,并正确顯示每人擁有的現金數。每次最多可以轉移三張紙币,紙币的金額可以是5美元、10美元或者20美元。

程式運作後的效果如圖1所示,我們點選“張三”右邊的“5美元”“10美元”“20美元”按鈕,再點選“Play”按鈕,便完成了現金從“張三”向“李四”流動,流動後,“張三”擁有的現金變為135美元,而“李四”僅剩下65美元,運作後的效果如圖2所示。

WPF中使用VisualBrush的執行個體

圖1  初始狀态圖

WPF中使用VisualBrush的執行個體

圖2 現金流動後的分布圖

在點選“張三”右邊的“5美元”“10美元”或者“20美元”按鈕時,會将“5美元”“10美元”或者“20美元”按鈕複制一份進“張三”與“李四”之間的“待支付區”,而完成這個操作就需要使用到VisualBrush。

WPF中使用VisualBrush的執行個體

圖3 現金流進待支付區的示意圖

點選“Cancel”按鈕可以清空“待支付區”中的按鈕。

VisualBrush是WPF畫刷類Brush的派生類,Brush類是個抽象類,WPF中派生自Brush類的還有:SolidColorBrush(實心畫刷)、LinearGradientBrush(線性漸變畫刷)、RadialGradientBrush(徑向漸變畫刷)、ImageBrush、DrawingBrush等。VisualBrush使用Visual對象來繪制區域,Visual對象包括Button、Page等。本例中使用VisualBrush來繪制Rectangle的Fill,最終達到的效果就是将按鈕複制進“待支付區”。這部分操作的代碼如下所示。

private void AddChildren(Button btn)
{
     VisualBrush vBrush = new VisualBrush(btn);
     Rectangle rect = new Rectangle();
     rect.Width = btn.ActualWidth;
     rect.Height = btn.ActualHeight;
     rect.Fill = vBrush;
     rect.Opacity = 0.8;
     this.StackPanel_Pay.Children.Add(rect);
}
           

代碼中,使用按鈕初始化VisualBrush,接着,按照按鈕的寬度和高度繪制矩形,并将矩形的Fill屬性設定為VisualBrush對象,最後将新繪制的矩形添加進“待支付區”。 好了,就到這裡了。

下面附上本例的完整代碼。

MainWindow.xaml檔案代碼

<Window x:Class="WpfVisualBrushExp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="你來我往" Height="350" Width="525" WindowStyle="ToolWindow">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="0.2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="0.2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
            <ColumnDefinition Width="0.05*"></ColumnDefinition>
            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <TextBlock Text="張三擁有" Grid.Row="1" Grid.Column="0" HorizontalAlignment="Right" Margin="0,10,0,10" />
        <TextBlock x:Name="TextBlock_ZhangsanAmount" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Margin="0,10,0,10" />
        <TextBlock Text="美元" Grid.Row="1" Grid.Column="2" HorizontalAlignment="Left" Margin="0,10,0,10" />
        <Button x:Name="Button_ToLisiFive" Content="5美元" Grid.Row="0" Grid.Column="4" Click="Button_ToLisiFive_Click" />
        <Button x:Name="Button_ToLisiTen" Content="10美元" Grid.Row="1" Grid.Column="4" Click="Button_ToLisiTen_Click" />
        <Button x:Name="Button_ToLisiTwenty" Content="20美元" Grid.Row="2" Grid.Column="4" Click="Button_ToLisiTwenty_Click" />
        
        <TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="5" Background="Cyan"/>
 
        <StackPanel x:Name="StackPanel_Pay" Background="White" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3" Orientation="Horizontal"/>
 
        <StackPanel Grid.Row="4" Grid.Column="4">
            <Button x:Name="Button_Pay" Content="Pay"  Click="Button_Pay_Click" />
            <Button x:Name="Button_Cancel" Content="Cancel" Click="Button_Cancel_Click" />
        </StackPanel>
                      
        <TextBlock Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="5" Background="Cyan"/>
        
        <TextBlock Text="李四擁有" Grid.Row="7" Grid.Column="0" HorizontalAlignment="Right" Margin="0,10,0,10" />
        <TextBlock x:Name="TextBlock_LisiAmount" Grid.Row="7" Grid.Column="1" HorizontalAlignment="Center" Margin="0,10,0,10" />
        <TextBlock Text="美元" Grid.Row="7" Grid.Column="2" HorizontalAlignment="Left" Margin="0,10,0,10" />
        <Button x:Name="Button_ToZhangsanFive" Content="5美元" Grid.Row="6" Grid.Column="4" Click="Button_ToZhangsanFive_Click" />
        <Button x:Name="Button_ToZhangsanTen" Content="10美元" Grid.Row="7" Grid.Column="4" Click="Button_ToZhangsanTen_Click" />
        <Button x:Name="Button_ToZhangsanTwenty" Content="20美元" Grid.Row="8" Grid.Column="4" Click="Button_ToZhangsanTwenty_Click" />
 
        <TextBlock Grid.Row="0" Grid.Column="3" Grid.RowSpan="9" Background="Cyan"/>
    </Grid>
</Window>
           

MainWindow.xaml.cs檔案代碼

//************************************************************  
//  
// VisualBrush示例代碼  
//  
// Author:三五月兒  
//   
// Date:2014/08/26 
//  
// http://blog.csdn.net/yl2isoft  
//  
//************************************************************  
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
 
namespace WpfVisualBrushExp
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        bool isZhangsanPaying = false;
        bool isLisiPaying = false;
        List<int> zhangsanPayAmountList = new List<int>();
        List<int> lisiPayAmountList = new List<int>();
 
        public MainWindow()
        {
            InitializeComponent();
            this.TextBlock_ZhangsanAmount.Text = "100";
            this.TextBlock_LisiAmount.Text = "100";
        }
 
        #region 張三
        private void Button_ToLisiFive_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount()
                || ReturnByLisiIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToLisiFive);
            zhangsanPayAmountList.Add(5);
            isZhangsanPaying = true;
        }
 
        private void Button_ToLisiTen_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount()
                || ReturnByLisiIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToLisiTen);
            zhangsanPayAmountList.Add(10);
            isZhangsanPaying = true;
        }
 
        private void Button_ToLisiTwenty_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount() 
                || ReturnByLisiIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToLisiTwenty);
            zhangsanPayAmountList.Add(20);
            isZhangsanPaying = true;
        }
        #endregion //張三
 
        #region 李四
        private void Button_ToZhangsanFive_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount()
                || ReturnByZhangsanIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToZhangsanFive);
            lisiPayAmountList.Add(5);
            isLisiPaying = true;
        }
 
        private void Button_ToZhangsanTen_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount()
                || ReturnByZhangsanIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToZhangsanTen);
            lisiPayAmountList.Add(10);
            isLisiPaying = true;
        }
 
        private void Button_ToZhangsanTwenty_Click(object sender, RoutedEventArgs e)
        {
            if (ReturnByMaxCount()
                || ReturnByZhangsanIsPaying())
            {
                return;
            }
            AddChildren(this.Button_ToZhangsanTwenty);
            lisiPayAmountList.Add(20);
            isLisiPaying = true;
        }
        #endregion //李四
 
        private bool ReturnByMaxCount()
        {
            if (this.StackPanel_Pay.Children.Count >= 3)
            {
                MessageBox.Show("一次最多隻能支付3張美元。");
                return true;
            }
            return false;
        }
 
        private bool ReturnByZhangsanIsPaying()
        {
            if (isZhangsanPaying == true)
            {
                MessageBox.Show("張三正在支付中...");
                return true;
            }
            return false;
        }
 
        private bool ReturnByLisiIsPaying()
        {
            if (isLisiPaying == true)
            {
                MessageBox.Show("李四正在支付中...");
                return true;
            }
            return false;
        }
 
        private void AddChildren(Button btn)
        {
            VisualBrush vBrush = new VisualBrush(btn);
            Rectangle rect = new Rectangle();
            rect.Width = btn.ActualWidth;
            rect.Height = btn.ActualHeight;
            rect.Fill = vBrush;
            rect.Opacity = 0.8;
            this.StackPanel_Pay.Children.Add(rect);
        }
 
        private void Button_Pay_Click(object sender, RoutedEventArgs e)
        {
            if (isZhangsanPaying)
            {
                int zhangsanAmount = Convert.ToInt32(this.TextBlock_ZhangsanAmount.Text) - zhangsanPayAmountList.Sum(it => it);
                int lisiAmount = Convert.ToInt32(this.TextBlock_LisiAmount.Text) + zhangsanPayAmountList.Sum(it => it);
                this.TextBlock_ZhangsanAmount.Text = zhangsanAmount.ToString();
                this.TextBlock_LisiAmount.Text = lisiAmount.ToString();
                zhangsanPayAmountList.Clear();
                isZhangsanPaying = false;
            }
            else
            {
                int lisiAmount = Convert.ToInt32(this.TextBlock_LisiAmount.Text) - lisiPayAmountList.Sum(it => it);
                int zhangsanAmount = Convert.ToInt32(this.TextBlock_ZhangsanAmount.Text) + lisiPayAmountList.Sum(it => it);
                this.TextBlock_LisiAmount.Text = lisiAmount.ToString();
                this.TextBlock_ZhangsanAmount.Text = zhangsanAmount.ToString();
                lisiPayAmountList.Clear();
                isLisiPaying = false;
            }
            this.StackPanel_Pay.Children.Clear();
        }
 
        private void Button_Cancel_Click(object sender, RoutedEventArgs e)
        {
            this.StackPanel_Pay.Children.Clear();
            zhangsanPayAmountList.Clear();
            lisiPayAmountList.Clear();          
            isZhangsanPaying = false;
            isLisiPaying = false;
        }
    }
}