Silverlight——施工计划日报表(三)

  近来非常忙,睡觉时间都不够。这一篇,尽量说完整吧,由于时间紧,可能不会详细讲解。

  这一篇主要内容有:界面调整与布局、日期计划网格和内容绘制、提交事件(Silverlight调用JS函数)、进度条显示与隐藏(JS调用Silverlight函数)、左击选择时间段、右键菜单、设置完成状态、全屏等等。

  如果各位有啥好建议或者代码有不当之处,请各位不要吝啬口水,尽管回复。有时间的话我会细看的。

  前面说过了的,就不重复了。

  最近做了一点小调整,主要是为了加入进度条。即点击提交时,进度条效果。如下所示: 

  image

Silverlight页面代码如下:

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit"  x:Class="PlansView.ShowPlans"
    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:BubbleCremeTheme="System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.BubbleCremeTheme"
    mc:Ignorable="d"
    d:DesignHeight="700" d:DesignWidth="800" Loaded="UserControl_Loaded">
    <toolkit:BubbleCremeTheme>
        <Canvas Name="cvMain">
            <Canvas Canvas.Top="3" Canvas.Left="5">
                <TextBlock Canvas.Top="3" Canvas.Left="200" Height="23" Name="txtTitle" HorizontalAlignment="Center" Text="标题" FontSize="18" FontWeight="Bold" Opacity="0.7" RenderTransformOrigin="0.5,0.5" >
                	<TextBlock.RenderTransform>
                		<CompositeTransform/>
                	</TextBlock.RenderTransform>
        	    <TextBlock.Foreground>
        		    <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
        			    <GradientStop Color="Black" Offset="1"/>
        			    <GradientStop Color="#FFE49C9C"/>
        		    </LinearGradientBrush>
        	    </TextBlock.Foreground>
                </TextBlock>
                <StackPanel Orientation="Horizontal" Canvas.Top="27" Name="spButtons" >
                    <Button Content="一键标记为完成" Name="btnFilishAll" Width="130" Margin="5,0,5,0" Click="btnFilishAll_Click" />
                    <Button Content="全屏" Name="BtnFullScreen" Width="100" Margin="5,0,5,0" Click="BtnFullScreen_Click" />
                    <Button Content="提交" Name="btnSubmit" Width="100"  Click="Button_Click" Margin="5,0,5,0"/>
                </StackPanel>

            </Canvas>
            <ScrollViewer HorizontalContentAlignment="Left" Canvas.Top="53" Canvas.Left="2" HorizontalAlignment="Left" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" 
                          Name="svPlans" MaxHeight="513">
                <ScrollViewer.BorderBrush>
                    <LinearGradientBrush EndPoint="0.5,1.5" StartPoint="0.5,0">
                        <GradientStop Color="#FFE0E3BC"/>
                        <GradientStop Color="#FF6C6C5C" Offset="1"/>
                    </LinearGradientBrush>
                </ScrollViewer.BorderBrush>
                <Border BorderBrush="#FF333333" BorderThickness="2" Background="#FFC1C1C1" >
                    <Grid x:Name="gdPlans" Background="#FFC1C1C1" MouseRightButtonDown="gdPlans_MouseRightButtonDown">

                    </Grid>
                </Border>
            </ScrollViewer>

            <Canvas Name="cvShowProcess" Width="600" Height="100">
                <Border BorderBrush="#FF4B1313" Opacity="0.8" MinHeight="100" MinWidth="600" BorderThickness="1" Canvas.Left="84" Canvas.Top="107">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="Black" Offset="0"/>
                            <GradientStop Color="#FFC29191" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                    <Canvas>
                        <ProgressBar Name="pbShowStatus" MinWidth="400" Height="30" Canvas.Top="50" Canvas.Left="100" IsIndeterminate="True"  />
                        <sdk:Label Name="lblLodingText"  FontWeight="ExtraBold" FontSize="20" Canvas.Left="220" Canvas.Top="10" Content="正在处理数据..." Foreground="#FFF7EDED"/>
                    </Canvas>
                </Border>
            </Canvas>
        </Canvas>
    </toolkit:BubbleCremeTheme>
</UserControl>

构造函数如下:

        public ShowPlans()
        {
            try
            {
                InitializeComponent();
                SetInitialValue();
                #region 设置显示的时间段
                if (DateType == "day" && txtTitle.Text.Length > 0)
                {
                    txtTitle.Text += string.Format("({0}~{1})", StartDate.ToShortDateString(), StartDate.AddDays(DateColCount).ToShortDateString());
                }
                #endregion
                //注册类型
                HtmlPage.RegisterScriptableObject("PlanView", this);
            }
            catch (Exception ex)
            {
                MessageBox.Show("参数初始化出错:" + ex.Message, "错误", MessageBoxButton.OK);
            }
        }

如上所示,该构造函数主要实现了参数初始化(请参考前两篇),注册托管对象以便JS调用(这里是为了在提交完成后js隐藏Silverlight进度条以及弹出消息框),属性设置等等。

提到了JS调用Silverlight函数,顺便说说下面定义的两个函数:

        /// <summary>
        /// 显示滚动条,支持js调用
        /// </summary>
        [ScriptableMember()]
        public void ShowProcessStatus()
        {
            cvShowProcess.Visibility = Visibility.Visible;
            btnFilishAll.IsEnabled = false;
            BtnFullScreen.IsEnabled = false;
            btnSubmit.IsEnabled = false;
        }
        /// <summary>
        /// 隐藏滚动条,支持js调用
        /// </summary>
        [ScriptableMember()]
        public void HideProcessStatus(string _msg)
        {
            cvShowProcess.Visibility = Visibility.Collapsed;
            btnFilishAll.IsEnabled = true;
            BtnFullScreen.IsEnabled = true;
            btnSubmit.IsEnabled = true;
            MessageBox.Show(_msg);
        }

注意特性“ScriptableMember”。在构造函数中注册了对象“PlanView”后,还需要将需要调用的函数加上特性“ScriptableMember”。这样就可以了么?还不行,还需要在ASP.NET页面写点js。如下所示:

    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
            width="100%" height="100%">
            <param name="source" value="ClientBin/PlansView.xap" />
            <param name="onError" value="onSilverlightError" />
            <param name="background" value="white" />
            <param name="minRuntimeVersion" value="4.0.50826.0" />
            <param name="onLoad" value="SilverlightLoaded" />
            <param name="autoUpgrade" value="true" />
            <param name="initParams" value='<%=InitParams %>' />
            <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration: none">
                <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="获取 Microsoft Silverlight"
                    style="border-style: none" />
            </a>
        </object>
        <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px;
            border: 0px"></iframe>
    </div>

注意“<param name="onLoad" value="SilverlightLoaded" /> ”,然后相应的JS如下:

    <script type="text/javascript">
          var slCtl = null;
        function SilverlightLoaded(sender) {
            slCtl = sender.getHost();
        }
        function PlanViewSave(Json) {
            //            alert(Json);
            setTimeout(
            function () {
                slCtl.Content.PlanView.HideProcessStatus("操作成功!");
            }, 6000
            );
        }
    </script>

也就是,在前台,我们可以很方便的用js调用Silverlight中的函数了。注意上面的“PlanView”,就是前面在构造函数中定义的对象。

接下来,在UserControl_Loaded事件中,对控件的位置进行了一些调整。

                #region 设置控件和进度条位置,并隐藏
                Canvas.SetLeft(spButtons, Application.Current.Host.Content.ActualWidth - 400);
                Canvas.SetLeft(txtTitle, Application.Current.Host.Content.ActualWidth / 2 - 150);
                Canvas.SetZIndex(cvShowProcess, 999);
                Canvas.SetLeft(cvShowProcess, Application.Current.Host.Content.ActualWidth / 3);
                Canvas.SetTop(cvShowProcess, 80);
                cvShowProcess.Visibility = Visibility.Collapsed;
                svPlans.Width = Application.Current.Host.Content.ActualWidth - 8;
                #endregion

值得注意的是,Application.Current.Host.Content.ActualWidth 在任何位置都能获取到宽度。而控件的Width等,在这里均无法获取到宽度和高度。

接下来介绍“SetColumnsAndRows”函数,该函数是设置列和行的。也就是生成网格。在页面上,已经放置了一个Grid的。Grid的是可以设置网格线的,不过似乎不能设置网格线的样式。因此,这里的网格线均使用的Border控件来完成。

时间紧,不能详细一一说明了,接下来的,直接贴代码好了。

具体代码如下:

        /// <summary>
        /// 设置列和行
        /// </summary>
        /// <param name="_lstPlansData"></param>
        private void SetColumnsAndRows(List<PlansData> _lstPlansData)
        {
            int _recWidth = 25;
            int _recHeight = 21;
            #region 生成文本列
            for (int i = 0; i < NameColumns; i++)
            {
                ColumnDefinition _col = new ColumnDefinition()
                {
                    MinWidth = 180,
                    Width = GridLength.Auto
                };
                gdPlans.ColumnDefinitions.Add(_col);
            }
            #endregion

            #region 生成日期列
            //第一列放置说明文字,第二列起才是日期列
            for (int i = 0; i < DateColCount + 1; i++)
            {
                ColumnDefinition _colDay = new ColumnDefinition();
                gdPlans.ColumnDefinitions.Add(_colDay);
            }
            #endregion

            #region 生成第一行
            RowDefinition _rowHead = new RowDefinition();
            gdPlans.RowDefinitions.Add(_rowHead);
            #endregion

            #region 设置表头
            for (int i = 0; i < NameColumns; i++)
            {
                TextBlock _txtPlansName = new TextBlock()
                {
                    Name = "txtPlansName" + i,
                    Text = PlanHeads[i],
                    FontWeight = FontWeights.Bold,
                    TextAlignment = TextAlignment.Center,
                    Foreground = SetHeadFontColor(),
                };

                Border _borPlansName = new Border()
                {
                    BorderThickness = new Thickness(1),
                    Background = SetHeadBackGround(),
                    BorderBrush = SetBorderColor(),
                    Child = _txtPlansName
                };

                Grid.SetColumn(_borPlansName, i);
                Grid.SetRow(_borPlansName, RowIndex);
                gdPlans.Children.Add(_borPlansName);
            }


            #region 设置列头模版字符串
            string _headTemp = "";
            if (DateType == "day")
            {
                _headTemp = "{0}";
            }
            else if (DateType == "week")
            {
                _headTemp = "{0}月{1}日~{2}月{3}日";
                _recWidth = 110;
            }
            else
            {
                _headTemp = "{0}年{1}月";
                _recWidth = 100;
            }
            #endregion
            #region 设置日期说明列头
            TextBlock _txtExplainHead = new TextBlock()
            {
                FontWeight = FontWeights.Bold,
                Foreground = SetHeadFontColor(),
            };
            Border _borExplain = new Border()
            {
                BorderBrush = SetBorderColor(),
                BorderThickness = new Thickness(1),
                Background = SetHeadBackGround(),
                Child = _txtExplainHead,
            };

            Grid.SetColumn(_borExplain, NameColumns);
            Grid.SetRow(_borExplain, RowIndex);
            gdPlans.Children.Add(_borExplain);
            #endregion
            #region 设置日期列头
            for (int i = 0; i < DateColCount; i++)
            {
                TextBlock _txtDay = new TextBlock()
                {
                    TextAlignment = TextAlignment.Center,
                    FontWeight = FontWeights.Bold,
                    Foreground = SetHeadFontColor(),
                };
                Border _borDay = new Border()
                {
                    BorderBrush = SetBorderColor(),
                    BorderThickness = new Thickness(1),
                    Child = _txtDay,
                    Background = SetHeadBackGround(),
                };

                #region 根据模版设置列头
                if (DateType == "week")
                {
                    DateTime _dtWeekStart = StartDate.AddDays(i * _weekDayCount);
                    DateTime _dtWeekEnd = _dtWeekStart.AddDays(_weekDayCount - 1);
                    //{0}月{1}日~{2}月{3}日
                    _txtDay.Text = string.Format(_headTemp, _dtWeekStart.Month, _dtWeekStart.Day, _dtWeekEnd.Month, _dtWeekEnd.Day);
                }
                else if (DateType == "day")
                {
                    //{0}
                    _txtDay.Text = string.Format(_headTemp, StartDate.AddDays(i).Day);
                }
                else if (DateType == "month")
                {
                    //{0}年{1}月
                    DateTime _dtMonth = StartDate.AddMonths(i);
                    _txtDay.Text = string.Format(_headTemp, _dtMonth.Year, _dtMonth.Month);
                }
                #endregion

                //文本列+日期说明列+日期列
                Grid.SetColumn(_borDay, i + NameColumns + 1);
                Grid.SetRow(_borDay, 0);
                gdPlans.Children.Add(_borDay);
            }
            #endregion
            #endregion

            #region 设置内容行
            RowIndex = 1;
            foreach (var item in _lstPlansData)
            {
                int _planColCount = 0;
                //生成内容行
                for (int i = 0; i < item.LstPlanDate.Count; i++)
                {
                    RowDefinition _row = new RowDefinition();
                    gdPlans.RowDefinitions.Add(_row);
                }
                //生成数据(文本头)
                foreach (var _plan in item.LstPlan)
                {
                    TextBlock _txtItemName = new TextBlock()
                    {
                        FontWeight = FontWeights.Bold,
                        FontSize = 13,
                        Padding = new Thickness(5, 2, 5, 0),
                        Text = _plan.PlanName,
                    };


                    Border _borItemName = new Border()
                    {
                        BorderBrush = SetBorderColor(),
                        BorderThickness = new Thickness(1),
                        Child = _txtItemName,
                        Background = SetContentBackGround()
                    };

                    Grid.SetColumn(_borItemName, _planColCount);
                    Grid.SetRow(_borItemName, RowIndex);
                    Grid.SetRowSpan(_borItemName, item.LstPlanDate.Count);
                    gdPlans.Children.Add(_borItemName);
                    _planColCount++;
                }

                //生成数据(日期)
                var _currentDateIndex = 0;
                foreach (var _planDate in item.LstPlanDate)
                {
                    bool _flagStart = false;
                    #region 设置日期说明列
                    TextBlock _txtExplain = new TextBlock()
                    {
                        Padding = new Thickness(5, 2, 5, 0),
                        FontWeight = FontWeights.Bold,
                        FontSize = 13,
                        Name = "txtDateExplain" + RowIndex,
                        Text = (_planDate.Explain ?? string.Empty) + (!_planDate.AllowBlank ? "*" : string.Empty),
                        Tag = _planDate,
                    };

                    Border _borItemExplain = new Border()
                    {
                        Name = "_borExplain" + RowIndex,
                        BorderBrush = SetBorderColor(),
                        BorderThickness = new Thickness(1),
                        Child = _txtExplain,
                    };
                    //设置完成状态
                    SetFilishState(_planDate.IsFlish, _borItemExplain);

                    Grid.SetColumn(_borItemExplain, NameColumns);
                    Grid.SetRow(_borItemExplain, RowIndex);
                    gdPlans.Children.Add(_borItemExplain);
                    #endregion

                    for (int i = 0; i < DateColCount; i++)
                    {
                        StackPanel _sp = new StackPanel()
                        {
                            HorizontalAlignment = HorizontalAlignment.Left,
                            Name = "SR" + RowIndex + "C" + (i + NameColumns),
                        };
                        Rectangle _rec = new Rectangle()
                        {
                            Name = "RR" + RowIndex + "C" + (i + NameColumns),
                            Width = _recWidth,
                            Height = _recHeight,
                            Cursor = Cursors.Hand,
                        };
                        SetDefaulStyle(_rec, _currentDateIndex);
                        //设置鼠标悬浮样式
                        _rec.MouseMove += new MouseEventHandler(_rec_MouseMove);
                        _rec.MouseLeave += new MouseEventHandler(_rec_MouseLeave);

                        #region 判断时间段,并设置时间段样式
                        if (DateType == "day")
                        {
                            //如果是第一天,并且仅此节点
                            if (_planDate.StartDate != null
                                && _planDate.StartDate.Equals(_planDate.EndDate)
                                && i == 0
                                && StartDate.AddDays(i).Date.Equals(_planDate.StartDate.Value.Date))
                            {
                                SetTimeSlotStyle(_rec, _currentDateIndex, true);
                            }
                            else if (_planDate.StartDate != null && !_flagStart && StartDate.AddDays(i).Date.Equals(_planDate.StartDate.Value.Date))
                            {
                                _flagStart = true;
                            }
                            else if (_planDate.EndDate != null && _flagStart && StartDate.AddDays(i).Date.Equals(_planDate.EndDate.Value.Date))
                            {
                                _flagStart = false;
                                SetTimeSlotStyle(_rec, _currentDateIndex, true);
                            }
                        }
                        else if (DateType == "week")
                        {
                            DateTime _dtWeekStart = StartDate.AddDays(i * _weekDayCount);
                            if (_planDate.StartDate != null
                                && !_flagStart)
                            {
                                //如果开始时间在周的时间段内,则设置为开始标签
                                if (_planDate.StartDate.Value.Date >= _dtWeekStart.Date && _planDate.StartDate.Value.Date <= _dtWeekStart.AddDays(_weekDayCount - 1).Date)
                                {
                                    _flagStart = true;
                                }
                            }
                            if (_planDate.EndDate != null && _flagStart)
                            {
                                if (_planDate.EndDate.Value.Date < _dtWeekStart.Date)
                                {
                                    _flagStart = false;
                                }
                            }
                        }
                        else if (DateType == "month")
                        {
                            //如果是第一月,并且仅此节点
                            if (_planDate.StartDate != null
                                && _planDate.EndDate != null
                                && _planDate.StartDate.Value.Month.Equals(_planDate.EndDate.Value.Month)
                                && _planDate.StartDate.Value.Year.Equals(_planDate.EndDate.Value.Year)
                                && i == 0
                                && StartDate.AddMonths(i).Month.Equals(_planDate.StartDate.Value.Month)
                                && StartDate.AddMonths(i).Year.Equals(_planDate.StartDate.Value.Year))
                            {
                                SetTimeSlotStyle(_rec, _currentDateIndex, true);
                            }
                            else if (_planDate.StartDate != null && !_flagStart
                                && StartDate.AddMonths(i).Date.Month.Equals(_planDate.StartDate.Value.Date.Month)
                                && StartDate.AddMonths(i).Date.Year.Equals(_planDate.StartDate.Value.Date.Year))
                            {
                                _flagStart = true;
                            }
                            else if (_planDate.EndDate != null && _flagStart
                                && StartDate.AddMonths(i).Date.Month.Equals(_planDate.EndDate.Value.Date.Month)
                                && StartDate.AddMonths(i).Date.Year.Equals(_planDate.EndDate.Value.Date.Year))
                            {
                                _flagStart = false;
                                SetTimeSlotStyle(_rec, _currentDateIndex, true);
                            }
                        }
                        if (_flagStart)
                        {
                            SetTimeSlotStyle(_rec, _currentDateIndex, true);
                        }
                        #endregion
                        if (!_planDate.IsReadOnly && (!_planDate.IsFlish))
                        {
                            _rec.MouseLeftButtonDown += new MouseButtonEventHandler(_rec_MouseLeftButtonDown);
                        }

                        if (!_planDate.IsFlish)
                        {
                            //设置右键菜单
                            ContextMenu SetDateContentMenu = new ContextMenu();
                            MenuItem _miFilish = new MenuItem()
                            {
                                Tag = _rec,
                                Header = "完成",
                            };
                            _miFilish.Click += new RoutedEventHandler(_miFilish_Click);
                            SetDateContentMenu.Items.Add(_miFilish);
                            ContextMenuService.SetContextMenu(_rec, SetDateContentMenu);
                        }
                        else
                        {
                            if (_planDate.AllowCancel)
                            {
                                //设置右键菜单
                                ContextMenu SetDateContentMenu = new ContextMenu();
                                //设置右键菜单
                                MenuItem _miCancelFilish = new MenuItem()
                                {
                                    Tag = _rec,
                                    Header = "撤销完成",
                                };
                                _miCancelFilish.Click += new RoutedEventHandler(_miCancelFilish_Click);
                                SetDateContentMenu.Items.Add(_miCancelFilish);
                                ContextMenuService.SetContextMenu(_rec, SetDateContentMenu);
                            }

                        }

                        _sp.Children.Add(_rec);
                        Border _borSP = new Border()
                        {
                            Name = "bR" + RowIndex + "C" + (i + NameColumns),
                            BorderBrush = SetBorderColor(),
                            BorderThickness = new Thickness(0.5),
                            Child = _sp,
                        };
                        //日期列列数+文本列+日期说明列
                        Grid.SetColumn(_borSP, i + NameColumns + 1);
                        Grid.SetRow(_borSP, RowIndex);
                        gdPlans.Children.Add(_borSP);
                    }
                    RowIndex++;
                    _currentDateIndex++;
                }
            }
            #endregion
        }
        /// <summary>
        /// 设置完成状态
        /// </summary>
        /// <param name="_currentRowIndex">当前行</param>
        private void SetFilishState(int _currentRowIndex, bool IsFilsh)
        {
            Border _bor = gdPlans.FindName("_borExplain" + _currentRowIndex) as Border;
            if (_bor != null)
            {
                SetFilishState(IsFilsh, _bor);
            }
        }
        /// <summary>
        /// 设置完成状态
        /// </summary>
        /// <param name="IsFilsh"></param>
        /// <param name="_bor"></param>
        private void SetFilishState(bool IsFilsh, Border _bor)
        {
            if (IsFilsh)
                _bor.Background = FilishImageBrush;
            else
                _bor.Background = SetContentBackGround();
        }

        #region 设置内容背景色
        private SolidColorBrush SetContentBackGround()
        {
            return new SolidColorBrush(ReturnColorFromString("FFd8d8d8"));
        }
        #endregion

        #region 设置表头背景色
        private SolidColorBrush SetHeadBackGround()
        {
            return new SolidColorBrush(ReturnColorFromString("FF7f7f7f"));
        }
        #endregion

        #region 设置表头颜色
        private SolidColorBrush SetHeadFontColor()
        {
            return new SolidColorBrush(ReturnColorFromString("FFffffff"));
        }
        #endregion

        #region 设置边框颜色
        private SolidColorBrush SetBorderColor()
        {
            SolidColorBrush _scb = new SolidColorBrush(ReturnColorFromString("FF333333"));
            return _scb;
        }
        #endregion

        #region 右键菜单(选择时间节点)
        void _mi_Click(object sender, RoutedEventArgs e)
        {
            MenuItem _mi = sender as MenuItem;
            if (_mi != null)
            {
                _rec_MouseLeftButtonDown(_mi.Tag, null);
            }
        }
        #endregion
        #region 右键菜单:完成
        void _miFilish_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                MenuItem _mi = sender as MenuItem;
                if (_mi != null)
                {
                    Rectangle _rec = _mi.Tag as Rectangle;
                    if (!SetFilishStatus(_rec))
                        return;
                }
                else
                {
                    MessageBox.Show("_miFilish_Click|_mi不能为NULL");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK);
            }
        }
        /// <summary>
        /// 设置完成,并保存数据
        /// </summary>
        /// <param name="_rec"></param>
        /// <returns></returns>
        private bool SetFilishStatus(Rectangle _rec)
        {
            if (_rec == null)
            {
                MessageBox.Show("_miFilish_Click|_rec不能为NULL");
                return false;
            }
            else
            {
                #region 设置参数
                int _currentRowIndex;
                int _currentColIndex;
                int _startColIndex;
                int _endColIndex;
                int _startDateIndex;
                int _endDateIndex;
                int _dateIndex;
                int _orgStartColIndex;
                int _orgEndColIndex;
                //设置参数
                SetRecParameters(_rec, out _currentRowIndex, out _currentColIndex, out _startColIndex, out _endColIndex, out _startDateIndex, out _endDateIndex, out _dateIndex, out _orgStartColIndex, out _orgEndColIndex);
                #endregion
                //如果时间段不存在
                if (_startColIndex == _endColIndex && _startColIndex == -1)
                {
                    MessageBoxResult _result = MessageBox.Show("您尚未选择时间段,确定要选择吗?", "温馨提示", MessageBoxButton.OKCancel);
                    if (_result == MessageBoxResult.OK)
                    {
                        _rec_MouseLeftButtonDown(_rec, null);
                        return false;
                    }
                }
                TextBlock _txt;
                PlanDate _planDate;
                if (!GetPlanDate(_currentRowIndex, out _txt, out _planDate))
                    return false;
                if (_planDate.IsFlish)
                    return false;
                //设置完成
                _planDate.IsFlish = true;
                _planDate.HasEdit = true;
                _txt.Tag = _planDate;
                //设置完成状态
                SetFilishState(_currentRowIndex, true);
                for (int i = 0; i < DateColCount; i++)
                {
                    var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + i) as Rectangle;
                    if (_recCurrent == null)
                        continue;
                    _recCurrent.MouseLeftButtonDown -= new MouseButtonEventHandler(_rec_MouseLeftButtonDown);
                    ////取消选择事件
                    //_recCurrent.MouseLeftButtonDown -= _rec_MouseLeftButtonDown;
                    //设置右键菜单
                    MenuItem _miCancelFilish = new MenuItem()
                    {
                        Tag = _recCurrent,
                        Header = "撤销完成",
                    };
                    _miCancelFilish.Click += new RoutedEventHandler(_miCancelFilish_Click);
                    ContextMenu _CM = new ContextMenu();
                    _CM.Items.Add(_miCancelFilish);
                    ContextMenuService.SetContextMenu(_recCurrent, _CM);
                }
                if (!HasShowSetFilishTip)
                {
                    MessageBox.Show("设置成功,请注意行首的颜色。", "温馨提示", MessageBoxButton.OK);
                    HasShowSetFilishTip = true;
                }
            }
            return true;
        }

        #region 撤销完成
        void _miCancelFilish_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                MenuItem _mi = sender as MenuItem;
                if (_mi != null)
                {
                    Rectangle _rec = _mi.Tag as Rectangle;
                    if (_rec == null)
                    {
                        MessageBox.Show("_miFilish_Click|_rec不能为NULL");
                        return;
                    }
                    else
                    {
                        #region 设置参数
                        int _currentRowIndex;
                        int _currentColIndex;
                        int _startColIndex;
                        int _endColIndex;
                        int _startDateIndex;
                        int _endDateIndex;
                        int _dateIndex;
                        int _orgStartColIndex;
                        int _orgEndColIndex;
                        //设置参数
                        SetRecParameters(_rec, out _currentRowIndex, out _currentColIndex, out _startColIndex, out _endColIndex, out _startDateIndex, out _endDateIndex, out _dateIndex, out _orgStartColIndex, out _orgEndColIndex);
                        #endregion

                        TextBlock _txt;
                        PlanDate _planDate;
                        if (!GetPlanDate(_currentRowIndex, out _txt, out _planDate))
                        {
                            return;
                        }
                        if (!_planDate.IsFlish)
                        {
                            return;
                        }
                        //设置完成
                        _planDate.IsFlish = false;
                        _planDate.HasEdit = true;
                        _planDate.IsReadOnly = false;
                        _txt.Tag = _planDate;
                        //设置完成状态
                        SetFilishState(_currentRowIndex, false);
                        for (int i = 0; i < DateColCount; i++)
                        {
                            var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + i) as Rectangle;
                            if (_recCurrent == null)
                            {
                                continue;
                            }
                            //添加
                            _recCurrent.MouseLeftButtonDown += new MouseButtonEventHandler(_rec_MouseLeftButtonDown);
                            //设置右键菜单
                            ContextMenu SetDateContentMenu = new ContextMenu();
                            MenuItem _miFilish = new MenuItem()
                            {
                                Tag = _recCurrent,
                                Header = "完成",
                            };
                            _miFilish.Click += new RoutedEventHandler(_miFilish_Click);
                            SetDateContentMenu.Items.Add(_miFilish);
                            ContextMenuService.SetContextMenu(_recCurrent, SetDateContentMenu);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("_miFilish_Click|_mi不能为NULL");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK);
            }
        }
        #endregion
        #endregion
        #region 单击左键选择时间节点
        void _rec_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                #region 选择时间点
                #region 设置参数
                Rectangle _rec = sender as Rectangle;
                if (_rec == null)
                {
                    return;
                }
                int _currentRowIndex;
                int _currentColIndex;
                int _startColIndex;
                int _endColIndex;
                int _startDateIndex;
                int _endDateIndex;
                int _dateIndex;
                int _orgStartColIndex;
                int _orgEndColIndex;
                //设置参数
                SetRecParameters(_rec, out _currentRowIndex, out _currentColIndex, out _startColIndex, out _endColIndex, out _startDateIndex, out _endDateIndex, out _dateIndex, out _orgStartColIndex, out _orgEndColIndex);
                #endregion

                if (_startDateIndex > _endDateIndex)
                {
                    MessageBox.Show("起始时间不对!" + _startDateIndex + "_" + _endDateIndex, "错误", MessageBoxButton.OK);
                    return;
                }

                TextBlock _txt;
                PlanDate _planDate;
                if (!GetPlanDate(_currentRowIndex, out _txt, out _planDate))
                {
                    return;
                }

                if (_startDateIndex == _endDateIndex && _startDateIndex == -1)
                {
                    _planDate.StartDate = _planDate.EndDate = null;
                }
                else if (DateType == "day")
                {
                    _planDate.StartDate = StartDate.AddDays(_startDateIndex);
                    _planDate.EndDate = StartDate.AddDays(_endDateIndex);
                }
                else if (DateType == "week")
                {
                    _planDate.StartDate = StartDate.AddDays(_startDateIndex * _weekDayCount);
                    _planDate.EndDate = StartDate.AddDays(_endDateIndex * _weekDayCount);
                }
                else if (DateType == "month")
                {
                    _planDate.StartDate = StartDate.AddMonths(_startDateIndex);
                    _planDate.EndDate = StartDate.AddMonths(_endDateIndex);
                }
                _planDate.HasEdit = true;
                #region 计划结束时间是否允许超过今天
                if (!_planDate.CanGreaterThanNow && _planDate.EndDate > DateTime.Now)
                {
                    MessageBox.Show("该计划的结束时间不能超过今天!", "错误", MessageBoxButton.OK);
                    return;
                }
                #endregion
                #region 是否限制了该计划的最小时间
                if (_planDate.MinDate != null && _planDate.StartDate != null && _planDate.StartDate < _planDate.MinDate)
                {
                    MessageBox.Show("该计划的开始时间不能小于" + _planDate.MinDate.Value.ToString("yyyy年MM月dd日") + "!", "错误", MessageBoxButton.OK);
                    return;
                }
                #endregion
                #region 是否设置了该计划的最大时间
                if (_planDate.MaxDate != null && _planDate.EndDate != null && _planDate.EndDate > _planDate.MaxDate)
                {
                    MessageBox.Show("该计划的开始时间不能大于" + _planDate.MaxDate.Value.ToString("yyyy年MM月dd日") + "!", "错误", MessageBoxButton.OK);
                    return;
                }
                #endregion
                for (int i = 0; i < DateColCount; i++)
                {
                    var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + (i + NameColumns)) as Rectangle;
                    if (_recCurrent != null && _recCurrent.Tag != null && _recCurrent.Tag.ToString().Substring(0, 1) == "1")
                    {
                        if (_startColIndex == -1)
                            _startColIndex = (i + NameColumns);
                        _endColIndex = (i + NameColumns);
                    }
                }
                #endregion
                #region 如果时间段不存在,则只设置当前节点
                if (_orgStartColIndex == _orgEndColIndex && _orgStartColIndex == -1)
                {
                    SetTimeSlotStyle(_rec, _dateIndex, true);
                    //_startDateIndex = _endDateIndex = (_currentColIndex - 1);
                }
                #endregion
                #region 如果当前列号小于时间段起点,则从当前节点开始染色到时间段的起点
                else if (_currentColIndex < _orgStartColIndex)
                {
                    for (int i = _currentColIndex; i < _orgStartColIndex; i++)
                    {
                        var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + i) as Rectangle;
                        if (_recCurrent != null)
                        {
                            SetTimeSlotStyle(_recCurrent, _dateIndex, true);
                        }
                    }
                    //_startDateIndex = _currentColIndex - 1; ;
                    //_endDateIndex = _orgEndColIndex - 1; ;
                }
                #endregion
                #region 如果当前列号大于时间段的终点,则从终点起开始染色到当前节点
                else if (_currentColIndex > _orgEndColIndex)
                {
                    for (int i = _orgEndColIndex; i <= _currentColIndex; i++)
                    {
                        var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + i) as Rectangle;
                        if (_recCurrent != null)
                        {
                            SetTimeSlotStyle(_recCurrent, _dateIndex, true);
                        }
                    }
                    //_startDateIndex = _orgStartColIndex - 1;
                    //_endDateIndex = _currentColIndex - 1;
                }
                #endregion
                #region 如果在时间段内
                else
                {
                    for (int i = _orgStartColIndex; i <= _currentColIndex; i++)
                    {
                        var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + i) as Rectangle;
                        if (_recCurrent != null)
                        {
                            SetDefaulStyle(_recCurrent, _dateIndex);
                        }
                    }
                    //如果当前所点不是取消所有
                    //if (_currentColIndex != _orgEndColIndex)
                    //{
                    //    _startDateIndex = _currentColIndex - 1;
                    //    _endDateIndex = _orgEndColIndex - 1;
                    //}
                }
                _txt.Tag = _planDate;
                //SaveChangeTime(_currentRowIndex, _startDateIndex, _endDateIndex, _txt);
                #endregion
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK);
            }
        }
        #endregion
        /// <summary>
        /// 获取PlanDate
        /// </summary>
        /// <param name="_currentRowIndex">当前行号</param>
        /// <param name="_txt">该对象所在的控件</param>
        /// <param name="_planDate">PlanDate对象</param>
        private bool GetPlanDate(int _currentRowIndex, out TextBlock _txt, out PlanDate _planDate)
        {
            _txt = gdPlans.FindName("txtDateExplain" + _currentRowIndex) as TextBlock;
            if (_txt == null)
            {
                MessageBox.Show("对象不存在,无法操作!", "错误", MessageBoxButton.OK);
                _planDate = null;
                return false;
            }
            _planDate = _txt.Tag as PlanDate;
            return true;
        }
        /// <summary>
        /// 根据矩形设置参数
        /// </summary>
        /// <param name="_rec">当前_rec</param>
        /// <param name="_currentRowIndex">当前对象的行序号</param>
        /// <param name="_currentColIndex">当前对象的列序号</param>
        /// <param name="_startColIndex">时间段的起点列序号</param>
        /// <param name="_endColIndex">时间段的终点列序号</param>
        /// <param name="_startDateIndex">开始日期序号</param>
        /// <param name="_endDateIndex">结束日期序号</param>
        /// <param name="_dateIndex">获取当前计划日期行序号</param>
        /// <param name="_orgStartColIndex">原始开始列</param>
        /// <param name="_orgEndColIndex">原始结束列</param>
        private void SetRecParameters(Rectangle _rec, out int _currentRowIndex, out int _currentColIndex, out int _startColIndex, out int _endColIndex, out int _startDateIndex, out int _endDateIndex, out int _dateIndex, out int _orgStartColIndex, out int _orgEndColIndex)
        {
            //当前对象的行序号
            _currentRowIndex = Convert.ToInt32(_rec.Name.Substring(2).Split('C')[0]);
            //当前对象的列序号
            _currentColIndex = Convert.ToInt32(_rec.Name.Substring(2).Split('C')[1]);
            //时间段的起点列序号
            _startColIndex = -1;
            //时间段的终点列序号
            _endColIndex = -1;
            //开始日期序号
            _startDateIndex = -1;
            //结束日期序号
            _endDateIndex = -1;
            ///获取当前计划日期行序号
            _dateIndex = Convert.ToInt32(_rec.Tag.ToString().Split('-')[1]);
            //设置时间段起始列序号
            GetStartColIndexAndEndColIndex(_currentRowIndex, ref _startColIndex, ref _endColIndex);

            #region 如果时间段不存在,则只设置当前节点
            if (_startColIndex == _endColIndex && _startColIndex == -1)
            {
                _startDateIndex = _endDateIndex = (_currentColIndex - 1);
            }
            #endregion
            #region 如果当前列号小于时间段起点,则从当前节点开始染色到时间段的起点
            else if (_currentColIndex < _startColIndex)
            {
                _startDateIndex = _currentColIndex - 1; ;
                _endDateIndex = _endColIndex - 1; ;
            }
            #endregion
            #region 如果当前列号大于时间段的终点,则从终点起开始染色到当前节点
            else if (_currentColIndex > _endColIndex)
            {
                _startDateIndex = _startColIndex - 1;
                _endDateIndex = _currentColIndex - 1;
            }
            #endregion
            #region 如果在时间段内
            else
            {
                //如果当前所点不是取消所有
                if (_currentColIndex != _endColIndex)
                {
                    _startDateIndex = _currentColIndex - 1;
                    _endDateIndex = _endColIndex - 1;
                }
            }
            _orgStartColIndex = _startColIndex;         //原始开始列
            _orgEndColIndex = _endColIndex;             //原始结束列
            #endregion
        }
        /// <summary>
        /// 获取时间段的起始列序号
        /// </summary>
        /// <param name="_currentRowIndex"></param>
        /// <param name="_startColIndex"></param>
        /// <param name="_endColIndex"></param>
        private void GetStartColIndexAndEndColIndex(int _currentRowIndex, ref int _startColIndex, ref int _endColIndex)
        {
            #region 获取时间段的起始列序号
            for (int i = 0; i < DateColCount; i++)
            {
                var _recCurrent = gdPlans.FindName("RR" + _currentRowIndex + "C" + (i + NameColumns)) as Rectangle;
                if (_recCurrent != null && _recCurrent.Tag != null && _recCurrent.Tag.ToString().Substring(0, 1) == "1")
                {
                    if (_startColIndex == -1)
                        _startColIndex = (i + NameColumns);
                    _endColIndex = (i + NameColumns);
                }
            }
            #endregion
        }
        void _rec_MouseLeave(object sender, MouseEventArgs e)
        {
            Rectangle _rec = sender as Rectangle;
            if (_rec != null && (_rec.Tag != null && _rec.Tag.ToString().Substring(0, 1) == "0"))
            {
                SetDefaulStyle(_rec, Convert.ToInt32(_rec.Tag.ToString().Split('-')[1]));
            }
        }
        void _rec_MouseMove(object sender, MouseEventArgs e)
        {
            Rectangle _rec = sender as Rectangle;
            if (_rec != null)
            {
                //当前对象的行序号
                int _currentRowIndex = Convert.ToInt32(_rec.Name.Substring(2).Split('C')[0]);
                TextBlock _txt = gdPlans.FindName("txtDateExplain" + _currentRowIndex) as TextBlock;
                PlanDate _planDate = _txt.Tag as PlanDate;
                //当前计划时间段行序号
                int _DateIndex = Convert.ToInt32(_rec.Tag.ToString().Split('-')[1]);
                if (_planDate.IsReadOnly == false && _rec.Tag.ToString().Substring(0, 1) == "0")
                {
                    SetTimeSlotStyle(_rec, _DateIndex, false);
                }
                if (_planDate == null || _planDate.StartDate == null || _planDate.EndDate == null)
                {
                    return;
                }
                //获取相差天数
                TimeSpan _ts1 = new TimeSpan(_planDate.StartDate.Value.Ticks);
                TimeSpan _ts2 = new TimeSpan(_planDate.EndDate.Value.Ticks);
                int _DifferDaysCount = _ts1.Subtract(_ts2).Duration().Days + 1;
                //设置提示
                ToolTip toolTipOnMouseOver = new ToolTip();
                StackPanel _spToolTip = new StackPanel()
                {
                    Orientation = Orientation.Vertical,
                    HorizontalAlignment = HorizontalAlignment.Left
                };
                Label _lblTitle = new Label()
                {
                    Content = _planDate.Explain ?? string.Empty,
                    FontWeight = FontWeights.Bold
                };
                _spToolTip.Children.Add(_lblTitle);
                StackPanel _spDaysCount = new StackPanel()
                {
                    Orientation = Orientation.Horizontal,
                    HorizontalAlignment = HorizontalAlignment.Left
                };
                _spToolTip.Children.Add(_spDaysCount);
                Image _img = new Image()
                {
                    Source = new BitmapImage(new Uri("Images/time.png", UriKind.Relative))
                };
                _spDaysCount.Children.Add(_img);
                if (_DifferDaysCount > 0)
                {

                    Label _lblDay = new Label()
                    {
                        Content = _DifferDaysCount + "天"
                    };
                    _spDaysCount.Children.Add(_lblDay);
                    Label _lblDate = new Label()
                    {
                        Content = "起止日期:" + _planDate.StartDate.Value.ToString("yy年MM月dd日")
                        + "~" + _planDate.EndDate.Value.ToString("yy年MM月dd日")
                    };
                    _spToolTip.Children.Add(_lblDate);
                }
                toolTipOnMouseOver.Content = _spToolTip;
                ToolTipService.SetToolTip(_rec, toolTipOnMouseOver);
                return;
            }
        }

        #region 设置样式
        private void SetDefaulStyle(Rectangle _rec, int _DateIndex)
        {
            _rec.Fill = new SolidColorBrush(Colors.White);
            _rec.Tag = "0-" + _DateIndex;
        }

        private static void SetTimeSlotStyle(Rectangle _rec, int _DateIndex, bool isInTimeSlotStyle)
        {
            if (_DateIndex < RowBackGroundLst.Count)
            {
                _rec.Fill = RowBackGroundLst[_DateIndex];
            }
            else
            {
                _rec.Fill = RowBackGroundLst[0];
            }
            string flag = string.Empty;
            if (isInTimeSlotStyle)
                flag = "1";
            else
                flag = "0";
            flag += "-" + _DateIndex;
            _rec.Tag = flag;
        }
        #endregion
        /// <summary>
        /// 获取颜色
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public Color ReturnColorFromString(string color)
        {
            string alpha = color.Substring(0, 2);
            string red = color.Substring(2, 2);
            string green = color.Substring(4, 2);
            string blue = color.Substring(6, 2);
            byte alphaByte = Convert.ToByte(alpha, 16);
            byte redByte = Convert.ToByte(red, 16);
            byte greenByte = Convert.ToByte(green, 16);
            byte blueByte = Convert.ToByte(blue, 16);
            return Color.FromArgb(alphaByte, redByte, greenByte, blueByte);
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int _rowIndex = 1;
                for (int i = 0; i < LstPlansData.Count; i++)
                {
                    for (int j = 0; j < LstPlansData[i].LstPlanDate.Count; j++)
                    {
                        TextBlock _txt = gdPlans.FindName("txtDateExplain" + _rowIndex) as TextBlock;
                        PlanDate _plan = _txt.Tag as PlanDate;
                        if (!_plan.AllowBlank)
                        {
                            if (_plan.StartDate == _plan.EndDate && _plan.EndDate == null)
                            {
                                MessageBox.Show(string.Format("您还有必选项[{0}-{1}]尚未选择,请选择!(带*号的为必选项。)", LstPlansData[i].LstPlan[0].PlanName, _plan.Explain), "警告", MessageBoxButton.OK);
                                return;
                            }
                            if (!_plan.IsFlish)
                            {
                                MessageBox.Show(string.Format("您还有必选项[{0}-{1}]尚未标记成完成,请标记!(带*号的为必标记项。)", LstPlansData[i].LstPlan[0].PlanName, _plan.Explain), "警告", MessageBoxButton.OK);
                                return;
                            }
                        }
                        LstPlansData[i].LstPlanDate[j] = _plan;
                        _rowIndex++;
                    }
                }
                //显示进度条
                ShowProcessStatus();
                //MessageBox.Show(JsonConvert.SerializeObject(_plan));
                ////SaveData();
                HtmlPage.Window.Invoke("PlanViewSave", JsonConvert.SerializeObject(LstPlansData, Formatting.Indented));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK);
            }
        }
        private void BtnFullScreen_Click(object sender, RoutedEventArgs e)
        {
            BtnFullScreen.Content = Application.Current.Host.Content.IsFullScreen ? "全屏" : "退出全屏";
            Application.Current.Host.Content.IsFullScreen = Application.Current.Host.Content.IsFullScreen ? false : true;
        }
        /// <summary>
        /// 一键标记为完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnFilishAll_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                int _rowIndex = 1;
                for (int i = 0; i < LstPlansData.Count; i++)
                {
                    for (int j = 0; j < LstPlansData[i].LstPlanDate.Count; j++)
                    {
                        TextBlock _txt = gdPlans.FindName("txtDateExplain" + _rowIndex) as TextBlock;
                        PlanDate _plan = _txt.Tag as PlanDate;
                        if (!_plan.AllowBlank)
                        {
                            if (_plan.StartDate == _plan.EndDate && _plan.EndDate == null)
                            {
                                MessageBox.Show(string.Format("您还有必选项[{0}-{1}]尚未选择,请选择!(带*号的为必选项。)", LstPlansData[i].LstPlan[0].PlanName, _plan.Explain), "警告", MessageBoxButton.OK);
                                return;
                            }
                        }
                        Rectangle _rec = gdPlans.FindName("RR" + _rowIndex + "C" + NameColumns) as Rectangle;
                        SetFilishStatus(_rec);
                        _rowIndex++;
                    }
                }
                MessageBox.Show("标记成功。您可以点击【提交】按钮来提交更改。", "温馨提示", MessageBoxButton.OK);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误", MessageBoxButton.OK);
            }
        }

        private void gdPlans_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;//屏蔽默认右键菜单
        }
posted @ 2011-06-03 13:29  雪雁  阅读(3359)  评论(5编辑  收藏  举报