// отсоединить заголовок и вернуть его internal OrderPanelHeader DetachHeader() { if ((this.grdHeader.Children.Count > 0) && (this.grdHeader.Children[0] is OrderPanelHeader)) { OrderPanelHeader retVal = (OrderPanelHeader)this.grdHeader.Children[0]; this.grdHeader.Children.Clear(); return(retVal); } else { return(null); } }
// ctor public OrderPanel(OrderViewModel orderView, int pageIndex, double width, bool isCreateHeaderPanel) { InitializeComponent(); _pageIndex = pageIndex; base.Width = width; _size = new Size(base.Width, double.PositiveInfinity); _orderView = orderView; if (orderView != null) { orderView.ViewPanel = this; } if (isCreateHeaderPanel) { // создать заголовок заказа OrderPanelHeader hdrPnl = new OrderPanelHeader(_orderView, width); // и добавить его к заказу this.grdHeader.Children.Add(hdrPnl); } // установить шрифт текстовых блоков в заголовке таблицы блюд double fontSize = (double)WpfHelper.GetAppGlobalValue("ordPnlDishTblHeaderFontSize"); // 10d double fontScale = (double)WpfHelper.GetAppGlobalValue("AppFontScale", 1.0d); _fontSize = fontSize * fontScale; IEnumerable <TextBlock> tbs = grdTblHeader.Children.OfType <TextBlock>(); foreach (TextBlock tb in tbs) { tb.FontSize = _fontSize; } //if (!orderView.DivisionColorRGB.IsNull()) //{ // brdOrder.BorderBrush = AppLib.GetBrushFromRGBString(orderView.DivisionColorRGB); // brdOrder.BorderThickness = new Thickness(10d); // brdOrder.CornerRadius = (isCreateHeaderPanel) ? new CornerRadius(15d,15d,0,0) : new CornerRadius(0); //} }
} // DrawOrderPanelsOnPage // преобразование сплошной панели в коллекцию панелей по колонкам // панели записываются на канву временного размещения // входные параметры: // - OrderPanel ordPanel - сплошная панель, которую надо разбить по колонкам, эта панель уже измерена! private void splitOrderViewPanels(OrderPanel ordPanel, bool keepSplitOrderOnLastColumnByForward) { OrderPanel curPanel = null; double curPanelHeight = 0d; string orderLogInfo = string.Format("id: {0}, index: {1}, number: {2}, dishes: {3}", ordPanel.OrderViewModel.Id, ordPanel.OrderViewModel.Index, ordPanel.OrderViewModel.Number, ordPanel.OrderViewModel.Dishes.Count); // цикл по блокам заказа, смещая curDishIndex, пока curDishIndex не дойдет до граничного значения в соотв.напр-и double freeHeight = getFreeHeight(); double curBlockHeight; List <FrameworkElement> curBlock; while (true) { curBlock = getNextItemsBlock(ordPanel, true); // выбрали все блоки - установить координаты последней панели и выйти if (curBlock == null) { setLastPanelPosition(curPanel, curPanelHeight); break; // нормальный выход - выбраны все элементы панели } // создать панель без заголовка, в которую будем переносить панели блюд if (curPanel == null) { curPanel = new OrderPanel(ordPanel.OrderViewModel, 0, ordPanel.Width, false); if (_shiftForward) { _canvas.Children.Add(curPanel); } else { _canvas.Children.Insert(0, curPanel); } // измерить панель measurePanel(curPanel); curPanelHeight = curPanel.PanelHeight; } // добавить заголовок заказа в панель, если при прямом проходе блок самый первый // иначе - добавлять в панель на последнем блоке из ordPanel if (_shiftForward && (curPanel.HeaderPanel == null) && (ordPanel.HeaderPanel != null)) { OrderPanelHeader header = ordPanel.DetachHeader(); curPanel.HeaderPanel = header; curPanelHeight += header.PanelHeight; } curBlockHeight = getBlockHeight(curBlock); // при обратном проходе и отсутствии элементов в ordPanel, // к curBlockHeight прибавить высоту заголовка и шапки таблицы блюд if (!_shiftForward && ((ordPanel.ItemsCount == 0) && (curPanel.HeaderPanel == null) && (ordPanel.HeaderPanel != null)) ) { curBlockHeight += ordPanel.HeaderHeight; if (curPanel.ItemsCount == 0) { curBlockHeight += ordPanel.DishTableHeaderHeight; } } // анализ размещения блока в свободном месте if (curPanelHeight + curBlockHeight <= freeHeight) { // при прямом проходе, добавить текущий блок элементов в конец панели заказа if (_shiftForward) { curPanel.AddDishes(curBlock); curPanelHeight += curBlockHeight; } // при обратном проходе, вставить блок в начало коллекции else { curPanel.InsertDishes(0, curBlock); curPanelHeight += curBlockHeight; // и не забываем про заголовок заказа при обратном проходе if ((ordPanel.ItemsCount == 0) && (curPanel.HeaderPanel == null) && (ordPanel.HeaderPanel != null)) { OrderPanelHeader header = ordPanel.DetachHeader(); curPanel.HeaderPanel = header; // высота заголовка заказа уже есть в curBlockHeight } } } // переход в следующий/предыдущий столбец else { // движение вперед, переход в следующий столбец if (_shiftForward) { // из последнего столбца #region из последнего столбца if (curColIndex == _pageColsCount) { // если панель заказа в последней колонке является продолжением заказа, т.е. HeaderPanel==null, то обрываем заказ и добавляем разделитель продолжения if (((curPanel.HeaderPanel == null) || keepSplitOrderOnLastColumnByForward) && (curPanel.ItemsCount > 0)) { // добавляем в конце разделитель продолжения заказа DishDelimeterPanel delimPanel = createContinuePanel(true); // удалить последний блок if (curPanelHeight + _continuePanelHeight > freeHeight) { _shiftForward = false; // смещаясь назад curBlock = getNextItemsBlock(curPanel, true); // поиск блока и удаление его _shiftForward = true; // восстановить смещение // если текущая панель не пустая, то добавляем панель переноса if ((curBlock != null) && (curPanel.ItemsCount > 0)) { curPanel.AddDelimiter(delimPanel); setPanelLeftTop(curPanel); } // иначе полностью переносим панель заказа в след.страницу else { _canvas.Children.Remove(curPanel); } } else { curPanel.AddDelimiter(delimPanel); setPanelLeftTop(curPanel); } } // иначе полностью переносим панель заказа в след.страницу else { _canvas.Children.Remove(curPanel); } // перенос панели на следующую страницу _pageBreak = true; break; } // из последнего столбца #endregion // из НЕпоследнего столбца: создаем новую панель (Top=0) #region из НЕпоследнего столбца else { // в текущей панели нет элементов или только одна панель DishPanel - // переносим панель в следующую колонку //if ((curPanel.DishPanels.Count == 0) || (curPanel.DishPanelsCount() == 1)) if (curPanel.DishPanels.Count == 0) { curPanel.AddDishes(curBlock); // добавить текущий блок элементов curPanelHeight += curBlockHeight; curColIndex++; curTopValue = 0d; // следующая колонка setPanelLeftTop(curPanel); } // размещение предыдущей панели по текущим координатам и создание новой панели else { setPanelLeftTop(curPanel); // новая панель без заголовка заказа curPanel = new OrderPanel(ordPanel.OrderViewModel, 0, ordPanel.Width, false); curPanel.AddDishes(curBlock); // добавить текущий блок элементов _canvas.Children.Add(curPanel); measurePanel(curPanel); curPanelHeight = curPanel.PanelHeight; // координаты следующего столбца curColIndex++; curTopValue = 0d; } freeHeight = getFreeHeight(); } #endregion } // движение назад, переход в предыдущий столбец else { // из первого столбца #region из первого столбца if (curColIndex == 1) { // если в текущей панели еще нет строк, то переносим всю панель на предыдущий лист // удалив текущую пустую панель if (curPanel.ItemsCount == 0) { _canvas.Children.Remove(curPanel); } // если в текущей панели уже есть блюда, т.е. есть что оставлять на текущей странице, // то добавляем в начало разделитель продолжения заказа и разделитель подачи else { DishDelimeterPanel contPanel = createContinuePanel(false); double delimPanelsHeight = _continuePanelHeight; // поиск номера подачи в блоке тек.панели (та, что остается на тек.странице) DishDelimeterPanel filingPanel = null; curBlock = getNextItemsBlock(curPanel, false, true); // блок НЕ удаляем!! if (curBlock != null) { int filingNumber = getFilingNumber(curBlock); if (filingNumber != 0) { filingPanel = createFilingPanel(filingNumber); // измерить высоту панели номера подачи //measurePanel(filingPanel); //double pnlHeight = getBlockHeight(new FrameworkElement[] { filingPanel }); //delimPanelsHeight += pnlHeight; } } bool keepPanel = true; //bool keepPanel = false; //// если разделитель не помещается, то удалить следующий блок из текущей панели //if (curPanelHeight + delimPanelsHeight > freeHeight) //{ // curBlock = getNextItemsBlock(curPanel, true, true); // // после удаления первого блока из текущ.панели остались блюда - добавляем разделитель // if ((curBlock != null) && (curPanel.ItemsCount > 0)) // { // keepPanel = true; // } // // иначе удаляем весь заказ со страницы - будет отрисован на предыду.странице // else // { // _canvas.Children.Remove(curPanel); // } //} //else //{ // keepPanel = true; //} // вставить разделители if (keepPanel) { curPanel.InsertDelimiter(0, contPanel); if (filingPanel != null) { curPanel.InsertDelimiter(0, filingPanel); } curTopValue = 0d; setPanelLeftTop(curPanel); } } // перенос панели на предыдущую страницу _pageBreak = true; break; } #endregion // из НЕпервого столбца - создаем новую панель #region из НЕпервого столбца - создаем новую панель else { // в текущей панели нет элементов - возвращаем блок и переносим панель НЕ разбивая ее if (curPanel.ItemsCount == 0) { curPanel.InsertDishes(0, curBlock); curPanelHeight += curBlockHeight; } // размещение предыдущей панели по текущим координатам и создание новой панели else { curTopValue = 0d; setPanelLeftTop(curPanel); // новая панель curPanel = new OrderPanel(ordPanel.OrderViewModel, 0, ordPanel.Width, false); curPanel.InsertDishes(0, curBlock); // добавить текущий блок элементов _canvas.Children.Insert(0, curPanel); measurePanel(curPanel); curPanelHeight = curPanel.PanelHeight; } // еще раз проверить перенос заголовка панели заказа if ((ordPanel.ItemsCount == 0) && (curPanel.HeaderPanel == null) && (ordPanel.HeaderPanel != null)) { OrderPanelHeader header = ordPanel.DetachHeader(); curPanel.HeaderPanel = header; curPanelHeight += header.PanelHeight; } curColIndex--; curTopValue = _colHeight; freeHeight = getFreeHeight(); } #endregion } } } return; }
// CTOR public OrderPanel(OrderViewModel orderView, int pageIndex, double width, bool isCreateHeaderPanel) { base.Width = width; this.SnapsToDevicePixels = true; _order = orderView; if (_order != null) { orderView.ViewPanel = this; } _pageIndex = pageIndex; _size = new Size(base.Width, double.PositiveInfinity); // установить шрифт текстовых блоков в заголовке таблицы блюд double fontScale = (double)WpfHelper.GetAppGlobalValue("AppFontScale", 1.0d); double fontSize = (double)WpfHelper.GetAppGlobalValue("ordPnlDishTblHeaderFontSize", 10d); _fontSize = fontSize * fontScale; // стиль текстовых блоков Style tblStyle = new Style(typeof(TextBlock)); tblStyle.Setters.Add(new Setter(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center)); tblStyle.Setters.Add(new Setter(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Center)); this.BorderThickness = new Thickness(0d); Grid grdOrderPanel = new Grid(); // 0.строка заголовка заказа, может содержать OrderPanelHeader grdOrderPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) }); // 1. заголовок таблицы блюд grdOrderPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) }); // 2. строка блюд grdOrderPanel.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(0, GridUnitType.Auto) }); // 0.строка заголовка заказа, может содержать OrderPanelHeader grdHeader = new Grid(); grdHeader.SetValue(Grid.RowProperty, 0); // создать заголовок заказа if (isCreateHeaderPanel) { OrderPanelHeader hdrPnl = new OrderPanelHeader(_order, width); // и добавить его к заказу this.grdHeader.Children.Add(hdrPnl); } grdOrderPanel.Children.Add(grdHeader); // 1. заголовок таблицы блюд brdTblHeader = new Border() { Background = Brushes.AliceBlue, BorderBrush = Brushes.DarkBlue, BorderThickness = new Thickness(1, 0, 1, 1) }; brdTblHeader.SetValue(Grid.RowProperty, 1); Grid grdTblHeader = new Grid(); // 0. № п/п grdTblHeader.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0.2d, GridUnitType.Star) }); // 1. наименование блюда grdTblHeader.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1.0d, GridUnitType.Star) }); // 2. количество grdTblHeader.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0.3d, GridUnitType.Star) }); // 3. таймер состояния grdTblHeader.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0.8d, GridUnitType.Star) }); TextBlock tblIndex = new TextBlock() { Text = "№", FontSize = _fontSize, Style = tblStyle }; tblIndex.SetValue(Grid.ColumnProperty, 0); grdTblHeader.Children.Add(tblIndex); TextBlock tblDishName = new TextBlock() { Text = "Блюдо", FontSize = _fontSize, Style = tblStyle }; tblDishName.SetValue(Grid.ColumnProperty, 1); grdTblHeader.Children.Add(tblDishName); TextBlock tblQty = new TextBlock() { Text = "Кол-во", FontSize = _fontSize, Style = tblStyle }; tblQty.SetValue(Grid.ColumnProperty, 2); grdTblHeader.Children.Add(tblQty); TextBlock tblTimer = new TextBlock() { Text = "Время", FontSize = _fontSize, Style = tblStyle }; tblTimer.SetValue(Grid.ColumnProperty, 3); grdTblHeader.Children.Add(tblTimer); brdTblHeader.Child = grdTblHeader; grdOrderPanel.Children.Add(brdTblHeader); // 2. строка блюд stkDishes = new StackPanel(); stkDishes.SetValue(Grid.RowProperty, 2); grdOrderPanel.Children.Add(stkDishes); this.Child = grdOrderPanel; //if (!orderView.DivisionColorRGB.IsNull()) //{ // brdOrder.BorderBrush = AppLib.GetBrushFromRGBString(orderView.DivisionColorRGB); // brdOrder.BorderThickness = new Thickness(10d); // brdOrder.CornerRadius = (isCreateHeaderPanel) ? new CornerRadius(15d,15d,0,0) : new CornerRadius(0); //} } // CTOR