how to check multiple row in DevExpress CheckEdit - c#

This is my code
gridView1.Columns.Add(new DevExpress.XtraGrid.Columns.GridColumn()
{
Caption = "Selected",
ColumnEdit = new RepositoryItemCheckEdit() { },
VisibleIndex = 1,
UnboundType = DevExpress.Data.UnboundColumnType.Boolean
});
But I cant check multiple checkEdit at the same time.
Why was that?
And please show me the way out.
Thanks.

Well, there are two answers to that question, one very simple, and one very complex, let's start with the simple:
If you want to have an column that has the "Selected" caption and act as a checkbox to indicate that a particular record was selected, you have two options:
1) If you can alter the class in your data source to add a property that is bool and could be used with DataBinding, then, all is done in a very simple way, jast add the property and bind the data and it will work:
class SimplePerson
{
public string Name { get; set; }
public bool IsSelected { get; set; }
}
BindingList<SimplePerson> source = new BindingList<SimplePerson>();
void InitGrid()
{
source.Add(new SimplePerson() { Name = "John", IsSelected = false });
source.Add(new SimplePerson() { Name = "Gabriel", IsSelected = true });
gridControl.DataSource = source;
}
2) You cannot alter you classes, so you need to this by signing the correct grid events and drawing the column yourself, and also adding the right handlers for all the actions.... is a very complex case, but for your luck i have this done, because i have had this problem in the past, so i will post you my full class!
public class GridCheckMarksSelection
{
public event EventHandler SelectionChanged;
protected GridView _view;
protected ArrayList _selection;
private GridColumn _column;
private RepositoryItemCheckEdit _edit;
public GridView View
{
get { return _view; }
set
{
if (_view == value)
return;
if (_view != null)
Detach();
_view = value;
Attach();
}
}
public GridColumn CheckMarkColumn { get { return _column; } }
public int SelectedCount { get { return _selection.Count; } }
public GridCheckMarksSelection()
{
_selection = new ArrayList();
}
public GridCheckMarksSelection(GridView view)
: this()
{
this.View = view;
}
protected virtual void Attach()
{
if (View == null)
return;
_selection.Clear();
_view = View;
_edit = View.GridControl.RepositoryItems.Add("CheckEdit")
as RepositoryItemCheckEdit;
_edit.EditValueChanged += edit_EditValueChanged;
_column = View.Columns.Insert(0);
_column.OptionsColumn.AllowSort = DefaultBoolean.False;
_column.VisibleIndex = int.MinValue;
_column.FieldName = "CheckMarkSelection";
_column.Caption = "Mark";
_column.OptionsColumn.ShowCaption = false;
_column.UnboundType = UnboundColumnType.Boolean;
_column.ColumnEdit = _edit;
View.CustomDrawColumnHeader += View_CustomDrawColumnHeader;
View.CustomDrawGroupRow += View_CustomDrawGroupRow;
View.CustomUnboundColumnData += view_CustomUnboundColumnData;
View.MouseUp += view_MouseUp;
}
protected virtual void Detach()
{
if (_view == null)
return;
if (_column != null)
_column.Dispose();
if (_edit != null)
{
_view.GridControl.RepositoryItems.Remove(_edit);
_edit.Dispose();
}
_view.CustomDrawColumnHeader -= View_CustomDrawColumnHeader;
_view.CustomDrawGroupRow -= View_CustomDrawGroupRow;
_view.CustomUnboundColumnData -= view_CustomUnboundColumnData;
_view.MouseDown -= view_MouseUp;
_view = null;
}
protected virtual void OnSelectionChanged(EventArgs e)
{
if (SelectionChanged != null)
SelectionChanged(this, e);
}
protected void DrawCheckBox(Graphics g, Rectangle r, bool Checked)
{
var info = _edit.CreateViewInfo() as CheckEditViewInfo;
var painter = _edit.CreatePainter() as CheckEditPainter;
ControlGraphicsInfoArgs args;
info.EditValue = Checked;
info.Bounds = r;
info.CalcViewInfo(g);
args = new ControlGraphicsInfoArgs(info, new GraphicsCache(g), r);
painter.Draw(args);
args.Cache.Dispose();
}
private void view_MouseUp(object sender, MouseEventArgs e)
{
if (e.Clicks == 1 && e.Button == MouseButtons.Left)
{
GridHitInfo info;
var pt = _view.GridControl.PointToClient(Control.MousePosition);
info = _view.CalcHitInfo(pt);
if (info.InRow && _view.IsDataRow(info.RowHandle))
UpdateSelection();
if (info.InColumn && info.Column == _column)
{
if (SelectedCount == _view.DataRowCount)
ClearSelection();
else
SelectAll();
}
if (info.InRow && _view.IsGroupRow(info.RowHandle)
&& info.HitTest != GridHitTest.RowGroupButton)
{
bool selected = IsGroupRowSelected(info.RowHandle);
SelectGroup(info.RowHandle, !selected);
}
}
}
private void View_CustomDrawColumnHeader
(object sender, ColumnHeaderCustomDrawEventArgs e)
{
if (e.Column != _column)
return;
e.Info.InnerElements.Clear();
e.Painter.DrawObject(e.Info);
DrawCheckBox(e.Graphics, e.Bounds, SelectedCount == _view.DataRowCount);
e.Handled = true;
}
private void View_CustomDrawGroupRow
(object sender, RowObjectCustomDrawEventArgs e)
{
var info = e.Info as GridGroupRowInfo;
info.GroupText = " " + info.GroupText.TrimStart();
e.Info.Paint.FillRectangle
(e.Graphics, e.Appearance.GetBackBrush(e.Cache), e.Bounds);
e.Painter.DrawObject(e.Info);
var r = info.ButtonBounds;
r.Offset(r.Width * 2, 0);
DrawCheckBox(e.Graphics, r, IsGroupRowSelected(e.RowHandle));
e.Handled = true;
}
private void view_CustomUnboundColumnData
(object sender, CustomColumnDataEventArgs e)
{
if (e.Column != CheckMarkColumn)
return;
if (e.IsGetData)
e.Value = IsRowSelected(View.GetRowHandle(e.ListSourceRowIndex));
else
SelectRow(View.GetRowHandle(e.ListSourceRowIndex), (bool)e.Value);
}
private void edit_EditValueChanged(object sender, EventArgs e)
{
_view.PostEditor();
}
private void SelectRow(int rowHandle, bool select, bool invalidate)
{
if (IsRowSelected(rowHandle) == select)
return;
object row = _view.GetRow(rowHandle);
if (select)
_selection.Add(row);
else
_selection.Remove(row);
if (invalidate)
Invalidate();
OnSelectionChanged(EventArgs.Empty);
}
public object GetSelectedRow(int index)
{
return _selection[index];
}
public int GetSelectedIndex(object row)
{
return _selection.IndexOf(row);
}
public void ClearSelection()
{
_selection.Clear();
View.ClearSelection();
Invalidate();
OnSelectionChanged(EventArgs.Empty);
}
private void Invalidate()
{
_view.CloseEditor();
_view.BeginUpdate();
_view.EndUpdate();
}
public void SelectAll()
{
_selection.Clear();
var dataSource = _view.DataSource as ICollection;
if (dataSource != null && dataSource.Count == _view.DataRowCount)
_selection.AddRange(dataSource); // fast
else
for (int i = 0; i < _view.DataRowCount; i++) // slow
_selection.Add(_view.GetRow(i));
Invalidate();
OnSelectionChanged(EventArgs.Empty);
}
public void SelectGroup(int rowHandle, bool select)
{
if (IsGroupRowSelected(rowHandle) && select) return;
for (int i = 0; i < _view.GetChildRowCount(rowHandle); i++)
{
int childRowHandle = _view.GetChildRowHandle(rowHandle, i);
if (_view.IsGroupRow(childRowHandle))
SelectGroup(childRowHandle, select);
else
SelectRow(childRowHandle, select, false);
}
Invalidate();
}
public void SelectRow(int rowHandle, bool select)
{
SelectRow(rowHandle, select, true);
}
public bool IsGroupRowSelected(int rowHandle)
{
for (int i = 0; i < _view.GetChildRowCount(rowHandle); i++)
{
int row = _view.GetChildRowHandle(rowHandle, i);
if (_view.IsGroupRow(row))
if (!IsGroupRowSelected(row))
return false;
else
if (!IsRowSelected(row))
return false;
}
return true;
}
public bool IsRowSelected(int rowHandle)
{
if (_view.IsGroupRow(rowHandle))
return IsGroupRowSelected(rowHandle);
object row = _view.GetRow(rowHandle);
return GetSelectedIndex(row) != -1;
}
public void UpdateSelection()
{
_selection.Clear();
Array.ForEach(View.GetSelectedRows(), item => SelectRow(item, true));
}
}
And now you need to know how to use this:
void InitGrid()
{
gridControl.DataSource = source;
// Do this after the database for the grid is set!
selectionHelper = new GridCheckMarksSelection(gridView1);
// Define where you want the column (0 = first)
selectionHelper.CheckMarkColumn.VisibleIndex = 0;
// You can even subscrive to the event that indicates that
// there was change in the selection.
selectionHelper.SelectionChanged += selectionHelper_SelectionChanged;
}
void selectionHelper_SelectionChanged(object sender, EventArgs e)
{
// Do something when the user selects or unselects something
}
But how do you retrieve all the selected items? There is a example assuming that the type bond is 'Person'
/// <summary>
/// Return all selected persons from the Grid
/// </summary>
public IList<Person> GetItems()
{
var ret = new List<Person>();
Array.ForEach
(
gridView1.GetSelectedRows(),
cell => ret.Add(gridView1.GetRow(cell) as Person)
);
return ret;
}

Related

Firebird Duplicating items C# .NET

We have a Till Software which also works with restaurants built on .NET (C#) and Firebird DB. We are having a strange problem recently, the items in an order are duplicating themselves when we go back to the order.
Strangely it's not the case always. It's happening only sometimes. I tried to figure out under what conditions it's happening but it's so random that it doesn't happen for a couple of days and then start duplicating items for the next two days.
The software is so huge that I don't know what code snippets to even post. As it's not happening always and is random I guess it doesn't have to do with the code but with Firebird DB maybe.
The other thing I wanted to mention is that we had a Firebird DB built on a 32-bit machine and when we tried to put it on a 64 - bit machine it didn't work. So, we had to take a backup of the DB on a 32-bit machine and restore it on a 64-bit machine and it worked with the software. I'm thinking does that have something to do with it? but we have another user on 32-bit with no conversion and it's the same case for him as well.
I'll really appreciate any help or guidance on this.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using Till_Library.Till_Controls;
using Till_Library.Till_Interfaces;
using Till_Library.Till_Presenters;
using Till_Library.Till_Types;
namespace Till_Library.Till_Views
{
public partial class viewOrderItems : UserControl
{
private IOrder mIOrder;
private PresenterOrder mPresenterOrder;
private readonly List<OrderGridItemRow> mOrderItemRowList;
private OrderGridItemRow mCurrentItemRow;
private readonly Color paidBckcolour = Color.GreenYellow;
private decimal mTillMode;
private readonly int ITEM_GRID_ROWS;
private int mItemGridStartIdx;
private int mItemGridEndIdx;
private int mLastDisplayedRowIdx;
private int mLastItemCount;
private bool mSplitMode;
public bool mIsRefund;
private RestTable mCurrentTable;
public delegate void TillCustDetailsClickedHandler();
public delegate void TillOrderItemPhoneClickedHandler();
public delegate void TillOrderTableSelectionClickedHandler();
public delegate void TillOrderTableCoverClickedHandler();
public delegate void TillOrderPriceClickedHandler(Point KeyPadLocation);
public delegate void TillOrderQuantityClickedHandler(Point KeyPadLocation);
public delegate void TillOrderItemClickedHandler(bool Option);
public delegate void TillOrderCheckBoxClickedHandler(OrderItemDetails pOrderItemRow);
public viewOrderItems(bool isRefund = false)
{
InitializeComponent();
ITEM_GRID_ROWS = 11;
mItemGridStartIdx = 0;
mItemGridEndIdx = ITEM_GRID_ROWS;
mIsRefund = isRefund;
int CurY = 0;
mIOrder = new IOrder();
mOrderItemRowList = new List<OrderGridItemRow>();
for (int i = 1; i <= ITEM_GRID_ROWS; i++)
{
CreateOrderItemRowControl(i, CurY);
CurY += 36;
}
}
private void CreateOrderItemRowControl(int pIdx, int pCurY)
{
string ItemRowName = "orderGridItemRow" + pIdx;
mOrderItemRowList.Add(new OrderGridItemRow(pIdx));
mOrderItemRowList[pIdx - 1].Name = ItemRowName;
mOrderItemRowList[pIdx - 1].Location = new Point(4, pCurY);
mOrderItemRowList[pIdx - 1].Parent = panItems;
//OrderItemRowList[pIdx - 1].Parent = panel2;
mOrderItemRowList[pIdx - 1].OrderItemClicked += TillOrderItemClicked;
mOrderItemRowList[pIdx - 1].OrderItemPriceClicked += TillOrderItemPriceClicked;
mOrderItemRowList[pIdx - 1].OrderItemPriceLeft += TillOrderItemPriceLeft;
mOrderItemRowList[pIdx - 1].OrderItemQuantityClicked += TillOrderItemQuantityClicked;
mOrderItemRowList[pIdx - 1].OrderCheckBoxClicked += OrderCheckboxClicked;
mOrderItemRowList[pIdx - 1].Visible = true;
mOrderItemRowList[pIdx - 1].SetOrderType(false);
mOrderItemRowList[pIdx - 1].IsRefund(mIsRefund);
}
[Category("Action")]
[Description("Cust Details clicked.")]
public event TillCustDetailsClickedHandler TillCustDetailsClicked;
protected virtual void OnCustDetailsClicked()
{
if (TillCustDetailsClicked != null)
{
//if(mTillMode != 3)
TillCustDetailsClicked(); // Notify Subscribers
}
}
public void AttachInterface(IOrder pIOrder)
{
mIOrder = pIOrder;
}
public void AttachPresenter(PresenterOrder pPresenter)
{
mPresenterOrder = pPresenter;
}
public void AttachOptions(IOptions pIOptions)
{
}
public void AttachTableControl(RestTable pTable)
{
if (pTable != null)
{
mCurrentTable = pTable;
labTableNo.Text = mCurrentTable.Name;
}
else
{
labTableNo.Text = "0";
labTableCovers.Text = "0";
}
}
public void SetTillMode(decimal pTillMode)
{
mTillMode = pTillMode;
if (mTillMode == 2) // Restaurant Mode
{
labTableNo.Visible = true;
labTableNoDesc.Visible = true;
labTableCovers.Visible = true;
labTableCoversDesc.Visible = true;
labCustName.Visible = false;
labCustNameTitle.Visible = false;
}
else if (mTillMode == 3) // Supermarket Mode
{
// This till mode also stops OnCustDetailsClicked() from firing
labTableNo.Visible = false;
labTableNoDesc.Visible = false;
labTableCovers.Visible = false;
labTableCoversDesc.Visible = false;
labCustName.Visible = false;
labCustNameTitle.Visible = false;
panPhone.Visible = false;
}
else // Takeaway Mode (Default)
{
labTableNo.Visible = false;
labTableNoDesc.Visible = false;
labTableCovers.Visible = false;
labTableCoversDesc.Visible = false;
labCustName.Visible = true;
labCustNameTitle.Visible = true;
}
}
public ORDERTYPE GetOrderType()
{
return mIOrder.mCurrentOrderDetails.OrderType;
}
public void DisplayOrder(bool pRecall, bool pMoveToLast = false)
{
mPresenterOrder.AttachOrderView(this);
mPresenterOrder.AttachOrderItemRowList(mOrderItemRowList);
if (mIOrder.mCurrentOrderItems.Count <= 11 && mIOrder.mCurrentOrderItems.Count > mLastItemCount &&
!pRecall && mTillMode == 3)
mPresenterOrder.ProcessPanelDisplayBETA(false);
else
mPresenterOrder.ProcessPanelDisplay(false, pMoveToLast); // time waster
mLastItemCount = mIOrder.mCurrentOrderItems.Count; // Accumulated Quantity Bug Fix & void ln
// DisplayOrderDetails();
}
public void DisplayOrderDetails()
{
labOrderNo.Text = mIOrder.mCurrentOrderDetails.OrderNo.ToString();
labCustNo.Text = mIOrder.mCurrentOrderDetails.OrderCustDetails.CustNo;
labTableNo.Text = mIOrder.mCurrentOrderDetails.OrderTableNo.ToString();
labTableCovers.Text = mIOrder.mCurrentOrderDetails.OrderTableCovers.ToString();
labCustNameTitle.Visible = false;
labCustName.Text = mIOrder.mCurrentOrderDetails.OrderCustDetails.CustName;
if (labCustName.Text != "")
{
labCustNameTitle.Visible = true;
}
//mPresenterOrder.UpdateTotals();
//labDeliveryAmt.Text = mIOrder.mCurrentOrderDetails.OrderDeliveryTotal.ToString("0.00");
//labDiscountAmt.Text = mIOrder.mCurrentOrderDetails.OrderDiscountPerc.ToString()+"%";
if (mIOrder.mCurrentOrderDetails.OrderDeliveryTotal > 0)
{
labDelivery.Text = "Delivery";
labDelivery.Visible = true;
labDeliveryAmt.Text = mIOrder.mCurrentOrderDetails.OrderDeliveryTotal.ToString("0.00");
}
else if (mTillMode == 3 && mIOrder.mCurrentOrderDetails.OrderQty > 0 &&
mIOrder.mCurrentOrderDetails.OrderVAT == 0)
{
labDelivery.Text = "Item Qty";
labDelivery.Visible = true;
labDeliveryAmt.Text = mIOrder.mCurrentOrderDetails.OrderQty.ToString();
}
else if (mIOrder.mCurrentOrderDetails.OrderVAT > 0)
{
labDelivery.Text = "VAT";
labDelivery.Visible = true;
labDeliveryAmt.Text = mIOrder.mCurrentOrderDetails.OrderVAT.ToString("0.00");
labDelivery.Font = new Font(labNetAmt.Font.FontFamily.Name, labNetAmt.Font.Size);
}
else
{
labDelivery.Visible = false;
labDeliveryAmt.Text = string.Empty;
}
if (mTillMode == 3 && mIOrder.mCurrentOrderDetails.OrderQty > 0 && mIOrder.mCurrentOrderDetails.OrderVAT > 0)
{
labDiscount.Text = "Item Qty";
labDiscount.Visible = true;
labDiscountAmt.Text = mIOrder.mCurrentOrderDetails.OrderQty.ToString();
}
else if (mIOrder.mCurrentOrderDetails.OrderDiscountAmt > 0)
{
labDiscount.Text = "Discount";
labDiscount.Visible = true;
labDiscountAmt.Text = mIOrder.mCurrentOrderDetails.OrderDiscountAmt.ToString("0.00");
}
else
{
labDiscount.Visible = false;
labDiscountAmt.Text = string.Empty;
}
double NetAmount = mIOrder.mCurrentOrderDetails.OrderNET;
// +mIOrder._mCurrentOrderDetails.OrderVAT;
if (mIOrder.mCurrentOrderDetails.OptionAddVATToPrice)
{
labNetAmt.Text = NetAmount.ToString("0.00");
labTotalAmt.Text =
(NetAmount + +mIOrder.mCurrentOrderDetails.OrderVAT +
mIOrder.mCurrentOrderDetails.OrderDeliveryTotal - mIOrder.mCurrentOrderDetails.OrderDiscountAmt)
.ToString("0.00");
}
else
{
labNetAmt.Text = (NetAmount - mIOrder.mCurrentOrderDetails.OrderVAT).ToString("0.00");
labTotalAmt.Text =
(NetAmount + mIOrder.mCurrentOrderDetails.OrderDeliveryTotal -
mIOrder.mCurrentOrderDetails.OrderDiscountAmt).ToString("0.00");
}
if (Convert.ToDouble(labTotalAmt.Text) < 0)
labTotalAmt.Text = "0.00";
CheckPaid();
}
public List<OrderGridItemRow> GetOrderItemRowList()
{
return mOrderItemRowList;
}
public IOrder GetIOrder()
{
return mIOrder;
}
public int GetPanelHeight()
{
return panItems.Height;
}
private void CheckPaid()
{
// RP Sets the total box to the local 'paidBckcolour' if the order displaied has been paid for, if not reverts back to default.
if ((mIOrder.mCurrentOrderDetails.OrderPayment >= mIOrder.mCurrentOrderDetails.OrderTotal) &&
mIOrder.mCurrentOrderDetails.OrderTotal != 0)
{
labDeliveryAmt.BackColor = paidBckcolour;
labDiscountAmt.BackColor = paidBckcolour;
labNetAmt.BackColor = paidBckcolour;
labTotalAmt.BackColor = paidBckcolour;
labDelivery.BackColor = paidBckcolour;
labDiscount.BackColor = paidBckcolour;
labNet.BackColor = paidBckcolour;
labTotal.BackColor = paidBckcolour;
}
else
{
labDeliveryAmt.BackColor = Color.WhiteSmoke;
labDiscountAmt.BackColor = Color.WhiteSmoke;
labNetAmt.BackColor = Color.WhiteSmoke;
labTotalAmt.BackColor = Color.WhiteSmoke;
labDelivery.BackColor = Color.WhiteSmoke;
labDiscount.BackColor = Color.WhiteSmoke;
labNet.BackColor = Color.WhiteSmoke;
labTotal.BackColor = Color.WhiteSmoke;
}
}
private void btnOrderItemGridUp_Click(object sender, EventArgs e)
{
// TODO
bool bFirstItem = false;
int OffsetIdx = 0;
int OrderItemRowListCount = mOrderItemRowList.Count;
if (OrderItemRowListCount > 0)
{
for (int i = 0; i < OrderItemRowListCount; i++)
{
if (mOrderItemRowList[i].Top >= 0)
{
OffsetIdx = i;
break;
}
}
}
mItemGridEndIdx = mItemGridStartIdx + OffsetIdx;
mItemGridStartIdx = mItemGridEndIdx - ITEM_GRID_ROWS;
if (mItemGridStartIdx < 0 && mItemGridEndIdx < ITEM_GRID_ROWS &&
(mItemGridStartIdx + mItemGridEndIdx + OffsetIdx < ITEM_GRID_ROWS))
{
bFirstItem = true;
mItemGridEndIdx = ITEM_GRID_ROWS;
}
if (!bFirstItem)
{
int GridRowOffset = mOrderItemRowList[mLastDisplayedRowIdx].Bottom - panItems.Height;
if (OrderItemRowListCount > 0 && GridRowOffset > 0)
{
for (int i = 0; i < OrderItemRowListCount; i++)
{
mOrderItemRowList[i].Location = new Point(1, mOrderItemRowList[i].Top - GridRowOffset);
}
}
}
setItemGridIndex(mItemGridStartIdx, mItemGridEndIdx);
mPresenterOrder.ProcessPanelDisplay(false);
mLastDisplayedRowIdx = mPresenterOrder.mLastDisplayedRowIdx;
mItemGridStartIdx = mPresenterOrder.mItemGridStartIdx;
mItemGridEndIdx = mPresenterOrder.mItemGridEndIdx;
}
private void btnOrderItemGridDown_Click(object sender, EventArgs e)
{
int OffsetIdx = 0;
int OrderItemListCount = mOrderItemRowList.Count;
if (OrderItemListCount > 0)
{
for (int i = 0; i < OrderItemListCount; i++)
{
if (mOrderItemRowList[i].Bottom > panItems.Height)
{
OffsetIdx = i;
break;
}
}
}
if (OffsetIdx == 0)
{
OffsetIdx = ITEM_GRID_ROWS;
}
if (mItemGridStartIdx + OffsetIdx <= mIOrder.mCurrentOrderItems.Count)
{
mItemGridStartIdx += OffsetIdx;
mItemGridEndIdx = mItemGridStartIdx + ITEM_GRID_ROWS;
setItemGridIndex(mItemGridStartIdx, mItemGridEndIdx);
mPresenterOrder.ProcessPanelDisplay(false);
mLastDisplayedRowIdx = mPresenterOrder.mLastDisplayedRowIdx;
mItemGridStartIdx = mPresenterOrder.mItemGridStartIdx;
mItemGridEndIdx = mPresenterOrder.mItemGridEndIdx;
//mPresenterOrder.DisplayOrderItems(mOrderItemRowList, panItems.Height);
}
}
private void setItemGridIndex(int pStartIndex, int pEndIndex)
{
if (pStartIndex < 0)
pStartIndex = 0;
mPresenterOrder.mItemGridStartIdx = pStartIndex;
mPresenterOrder.mItemGridEndIdx = pEndIndex;
mPresenterOrder.mLastDisplayedRowIdx = mLastDisplayedRowIdx;
// mLastDisplayedRowIdx = mPresenterOrder.mLastDisplayedRowIdx;
}
public void setSplitMode(bool pMode)
{
mSplitMode = pMode;
}
private void labCustNo_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void labCustNoDesc_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void labCustName_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void labCustNameTitle_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void labOrderNoDesc_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void labOrderNo_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
private void panCustInfo_Click(object sender, EventArgs e)
{
OnCustDetailsClicked();
}
public void TillMark2PrintClicked()
{
if (mIOrder.mCurrentOrderItems.Count > 0 && mCurrentItemRow != null)
{
mCurrentItemRow.SetMark2PrintOrderSelected(true);
foreach (TillOrderItem item in mIOrder.mCurrentOrderItems)
if (item.GetItemID() == mIOrder.mCurrentOrderItemID)
if (!item.GetMarked2Print())
item.SetMark2Print(true);
else
item.SetMark2Print(false);
}
}
public void TillMark2PrintReset()
{
foreach (TillOrderItem item in mIOrder.mCurrentOrderItems)
item.SetMark2Print(false);
}
[Category("Action")]
[Description("Order Item Price Clicked.")]
public event TillOrderPriceClickedHandler TillOrderPriceClicked;
protected virtual void OnTillOrderPriceClicked(Point pKeyPadLoc)
{
if (TillOrderPriceClicked != null)
{
TillOrderPriceClicked(pKeyPadLoc); // Notify Subscribers
}
}
private void TillOrderItemPriceClicked(OrderGridItemRow pOrderItemRow)
{
OnTillOrderPriceClicked(GetRowLocation(pOrderItemRow));
}
private Point GetRowLocation(OrderGridItemRow pOrderItemRow)
{
int mKeyPadX, mKeyPadY;
Point mFloutingKeypadLoc;
mCurrentItemRow = pOrderItemRow;
mKeyPadX = pOrderItemRow.Location.X + pOrderItemRow.Width + 2;
mKeyPadY = pOrderItemRow.Parent.Location.Y + pOrderItemRow.Location.Y + (pOrderItemRow.Height/2);
mPresenterOrder.ClearOrderItemGridSelections(false);
mIOrder.mCurrentOrderItemID = mCurrentItemRow.ItemID;
mFloutingKeypadLoc = new Point(mKeyPadX, mKeyPadY);
return mFloutingKeypadLoc;
}
private bool TillOrderItemPriceLeft(double pNewItemPrice, double pOldItemPrice)
{
if (pOldItemPrice >= 0)
{
if (pNewItemPrice >= 0)
{
if (SetTillItemPrice(pNewItemPrice))
return true;
}
}
else
{
if (pNewItemPrice < 0)
{
if (SetTillItemPrice(pNewItemPrice))
return true;
}
}
return false;
}
private bool SetTillItemPrice(double pNewItemPrice)
{
foreach (TillOrderItem Item in mIOrder.mCurrentOrderItems)
{
if (Item.GetItemID() == mIOrder.mCurrentOrderItemID)
{
Item.SetItemPrice(pNewItemPrice);
mPresenterOrder.UpdateTotals();
DisplayOrder(false);
return true;
}
}
return false;
}
[Category("Action")]
[Description("Order Item Quantity Clicked.")]
public event TillOrderQuantityClickedHandler TillOrderQuantityClicked;
protected virtual void OnTillOrderQuantityClicked(Point pKeyPadLoc)
{
if (TillOrderQuantityClicked != null)
{
TillOrderQuantityClicked(pKeyPadLoc); // Notify Subscribers
}
}
private void TillOrderItemQuantityClicked(OrderGridItemRow pOrderItemRow)
{
OnTillOrderQuantityClicked(GetRowLocation(pOrderItemRow));
}
public void SetItemQty()
{
mCurrentItemRow.RefreshItemRow();
if (mCurrentItemRow.ItemQty == 0)
mCurrentItemRow.ItemQty = 1;
mIOrder.mCurrentOrderItems[
mIOrder.mCurrentOrderItems.FindIndex(i => i.GetItemID() == mIOrder.mCurrentOrderItemID)].SetItemQty(
(int) mCurrentItemRow.ItemQty);
mPresenterOrder.UpdateTotals();
DisplayOrder(false);
}
private void TillOrderItemClicked(OrderGridItemRow pOrderItemRow)
{
mCurrentItemRow = pOrderItemRow;
mPresenterOrder.ClearOrderItemGridSelections(false);
mIOrder.mCurrentOrderItemID = pOrderItemRow.ItemID;
if (mSplitMode)
{
mPresenterOrder.SetAsSplitItem(mIOrder.mCurrentOrderItemID);
DisplayOrder(false);
mPresenterOrder.ProcessPanelDisplay(mSplitMode);
//mPresenterOrder.ProcessPanelDisplay(!mSplitMode);
}
else
{
mCurrentItemRow.SetOrderItemSelected(true);
ShowItemControls(true);
// viewfunc
}
}
public void UpdatePhone()
{
if ((string) picPhone1.Tag == "1")
{
picPhone1.BackgroundImage = Properties.Resources.phone_ringing;
panPhone.BackColor = Color.White;
picPhone1.Tag = "2";
}
else
{
picPhone1.BackgroundImage = Properties.Resources.phone1;
//picPhone1.BackColor = Color.Aqua;
panPhone.BackColor = Color.FromArgb(114, 205, 206);
picPhone1.Tag = "1";
}
}
[Category("Action")]
[Description("Order Item Phone Clicked.")]
public event TillOrderItemPhoneClickedHandler TillOrderItemPhoneClicked;
protected virtual void OnOrderItemPhoneClicked()
{
if (TillOrderItemPhoneClicked != null)
{
TillOrderItemPhoneClicked(); // Notify Subscribers
}
}
private void picPhone1_Click(object sender, EventArgs e)
{
OnOrderItemPhoneClicked();
}
public void ResetPhone()
{
picPhone1.BackgroundImage = Properties.Resources.phone1;
panPhone.BackColor = Color.Aqua;
picPhone1.BackColor = Color.Aqua;
picPhone1.Tag = "1";
}
public int getCurrentTableNo()
{
return Convert.ToInt32(labTableNo.Text);
}
[Category("Action")]
[Description("Order Item Clicked, Show Controls")]
public event TillOrderItemClickedHandler TillShowControls;
protected virtual void OnTillShowControls(bool pOption)
{
if (TillShowControls != null)
{
TillShowControls(true); // Notify Subscribers
}
}
private void OrderCheckboxClicked(OrderItemDetails pOrderItemRow)
{
OnOrderChecked(pOrderItemRow);
}
[Category("Action")]
[Description("Order Checkbox Clicked")]
public event TillOrderCheckBoxClickedHandler OrderChecked;
protected virtual void OnOrderChecked(OrderItemDetails pOrderItemRow)
{
if(OrderChecked != null)
{
OrderChecked(pOrderItemRow);
}
}
private void ShowItemControls(bool pOption)
{
OnTillShowControls(pOption);
}
[Category("Action")]
[Description("Assign Order to Table Clicked.")]
public event TillOrderTableSelectionClickedHandler TillOrderTableSelectionClicked;
protected virtual void OnTillOrderTableSelectionClicked()
{
if (TillOrderTableSelectionClicked != null)
{
TillOrderTableSelectionClicked(); // Notify Subscribers
}
}
private void panTableSel_Click(object sender, EventArgs e)
{
// Table Selections
Console.Write("Table Selection");
OnTillOrderTableSelectionClicked();
}
private void labTableNoDesc_Click(object sender, EventArgs e)
{
Console.Write("Table Selection");
OnTillOrderTableSelectionClicked();
}
private void labTableNo_Click(object sender, EventArgs e)
{
Console.Write("Table Selection");
OnTillOrderTableSelectionClicked();
}
[Category("Action")]
[Description("Assign Customers to Table Clicked.")]
public event TillOrderTableCoverClickedHandler TillOrderTableCoverClicked;
protected virtual void OnTillOrderTableCoverClicked()
{
if (TillOrderTableCoverClicked != null)
{
TillOrderTableCoverClicked(); // Notify Subscribers
}
}
private void panTableCov_Click(object sender, EventArgs e)
{
// No of People on Table, Selections
Console.Write("Table Covers");
OnTillOrderTableCoverClicked();
}
private void labTableCoversDesc_Click(object sender, EventArgs e)
{
Console.Write("Table Covers");
OnTillOrderTableCoverClicked();
}
private void labTableCovers_Click(object sender, EventArgs e)
{
Console.Write("Table Covers");
OnTillOrderTableCoverClicked();
}
}
}

How to change FreshTabbedNavigationContainer tabbed page to top and change icon and font size for ios in xamarin forms

I have using freshmvvm for my xamarin forms application. FreshTabbedNavigationContainer tabbed page is working fine with android. I have customized the android tabbed page font size, font color, image size. But in IOS I don't know how to change the tab bar from bottom to top like in android and how to change the size of the icon and font. Please anyone suggest me to done this. My tabbed page code is below,
var tabbedPage = new FreshTabbedNavigationContainer();
tabbedPage.AddTab<FirstPageModel>("One", "icon.png");
tabbedPage.AddTab<SecondPageModel>("Two", "icon.png");
await Application.Current.MainPage.Navigation.PushAsync(tabbedPage);
NavigationPage.SetHasNavigationBar(tabbedPage, false);
I have changed the tabbar scrollable using custom renderer for android like this,
public override void OnViewAdded(Android.Views.View child)
{
base.OnViewAdded(child);
var tabLayout = child as TabLayout;
if (tabLayout != null)
{
tabLayout.TabMode = TabLayout.ModeScrollable;
}
}
How to change the tab bar as scrollable for ios. In my tabbed page, the space between text and icon is zero. Please refer the screenshot.
Naxam's GitHub has sort of a similar implementation using a Customized version of Xamarin Forms TabbedPage, But since FreshTabbedNavigationContainer inherits from the same(TabbedPage) you can just use it instead and it should work like a charm.
public class TopTabbedPage : FreshTabbedNavigationContainer
{
public TopTabbedPage()
{
//BarBackgroundColor = Color.Blue;
//BarTextColor = Color.White;
}
public static readonly BindableProperty BarIndicatorColorProperty = BindableProperty.Create(
nameof(BarIndicatorColor),
typeof(Color),
typeof(TopTabbedPage),
Color.White,
BindingMode.OneWay);
public Color BarIndicatorColor
{
get { return (Color)GetValue(BarIndicatorColorProperty); }
set { SetValue(BarIndicatorColorProperty, value); }
}
public static readonly BindableProperty SwipeEnabledColorProperty = BindableProperty.Create(
nameof(SwipeEnabled),
typeof(bool),
typeof(TopTabbedPage),
true,
BindingMode.OneWay);
public bool SwipeEnabled
{
get { return (bool)GetValue(SwipeEnabledColorProperty); }
set { SetValue(SwipeEnabledColorProperty, value); }
}
}
And then the renderer would look something like this:
[assembly: ExportRenderer(typeof(TopTabbedPage), typeof(TopTabbedRenderer))]
namespace Naxam.Controls.Platform.iOS
{
using Platform = Xamarin.Forms.Platform.iOS.Platform;
using Forms = Xamarin.Forms.Forms;
public partial class TopTabbedRenderer :
UIViewController
{
public static void Init()
{
}
UIColor _defaultBarColor;
bool _defaultBarColorSet;
bool _loaded;
Size _queuedSize;
int lastSelectedIndex;
Page Page => Element as Page;
UIPageViewController pageViewController;
protected UIViewController SelectedViewController;
protected IList<UIViewController> ViewControllers;
protected IPageController PageController
{
get { return Page; }
}
protected TopTabbedPage Tabbed
{
get { return (TopTabbedPage)Element; }
}
protected TabsView TabBar;
private NSLayoutConstraint tabBarHeight;
public TopTabbedRenderer()
{
ViewControllers = new UIViewController[0];
pageViewController = new UIPageViewController(
UIPageViewControllerTransitionStyle.Scroll,
UIPageViewControllerNavigationOrientation.Horizontal,
UIPageViewControllerSpineLocation.None
);
TabBar = new TabsView
{
TranslatesAutoresizingMaskIntoConstraints = false
};
TabBar.TabsSelectionChanged += HandleTabsSelectionChanged;
}
public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
{
base.DidRotate(fromInterfaceOrientation);
View.SetNeedsLayout();
}
public override void ViewDidAppear(bool animated)
{
PageController.SendAppearing();
base.ViewDidAppear(animated);
}
public override void ViewDidDisappear(bool animated)
{
base.ViewDidDisappear(animated);
PageController.SendDisappearing();
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
View.AddSubview(TabBar);
AddChildViewController(pageViewController);
View.AddSubview(pageViewController.View);
pageViewController.View.TranslatesAutoresizingMaskIntoConstraints = false;
pageViewController.DidMoveToParentViewController(this);
var views = NSDictionary.FromObjectsAndKeys(
new NSObject[] {
TabBar,
pageViewController.View
},
new NSObject[] {
(NSString) "tabbar",
(NSString) "content"
}
);
View.AddConstraints(NSLayoutConstraint.FromVisualFormat("V:|-0-[tabbar]-0-[content]-0-|",
0,
null,
views));
View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[tabbar]-0-|",
0,
null,
views));
View.AddConstraints(NSLayoutConstraint.FromVisualFormat("H:|-0-[content]-0-|",
0,
null,
views));
tabBarHeight = NSLayoutConstraint.Create(
TabBar,
NSLayoutAttribute.Height,
NSLayoutRelation.Equal,
1, 68
);
TabBar.AddConstraint(tabBarHeight);
if (pageViewController.ViewControllers.Length == 0
&& lastSelectedIndex >= 0 || lastSelectedIndex < ViewControllers.Count)
{
pageViewController.SetViewControllers(
new[] { ViewControllers[lastSelectedIndex] },
UIPageViewControllerNavigationDirection.Forward,
true, null
);
}
UpdateSwipe(Tabbed.SwipeEnabled);
pageViewController.DidFinishAnimating += HandlePageViewControllerDidFinishAnimating;
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
PageController?.SendDisappearing();
if (Tabbed != null)
{
Tabbed.PropertyChanged -= OnPropertyChanged;
Tabbed.PagesChanged -= OnPagesChanged;
TabBar.TabsSelectionChanged -= HandleTabsSelectionChanged;
}
if (pageViewController != null)
{
pageViewController.WeakDataSource = null;
pageViewController.DidFinishAnimating -= HandlePageViewControllerDidFinishAnimating;
pageViewController?.Dispose();
}
}
base.Dispose(disposing);
}
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
{
ElementChanged?.Invoke(this, e);
}
UIViewController GetViewController(Page page)
{
var renderer = Platform.GetRenderer(page);
return renderer?.ViewController;
}
void OnPagePropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName != Page.TitleProperty.PropertyName)
return;
if (!(sender is Page page) || page.Title is null)
return;
TabBar.ReplaceItem(page.Title, Tabbed.Children.IndexOf(page));
}
void OnPagesChanged(object sender, NotifyCollectionChangedEventArgs e)
{
e.Apply((o, i, c) => SetupPage((Page)o, i), (o, i) => TeardownPage((Page)o, i), Reset);
SetControllers();
UIViewController controller = null;
if (Tabbed.CurrentPage != null)
{
controller = GetViewController(Tabbed.CurrentPage);
}
if (controller != null && controller != SelectedViewController)
{
SelectedViewController = controller;
var index = ViewControllers.IndexOf(SelectedViewController);
MoveToByIndex(index);
TabBar.SelectedIndex = index;
}
}
void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(TabbedPage.CurrentPage))
{
var current = Tabbed.CurrentPage;
if (current == null)
return;
var controller = GetViewController(current);
if (controller == null)
return;
SelectedViewController = controller;
var index = ViewControllers.IndexOf(SelectedViewController);
MoveToByIndex(index);
TabBar.SelectedIndex = index;
}
else if (e.PropertyName == TabbedPage.BarBackgroundColorProperty.PropertyName)
{
UpdateBarBackgroundColor();
}
else if (e.PropertyName == TabbedPage.BarTextColorProperty.PropertyName)
{
UpdateBarTextColor();
}
else if (e.PropertyName == TopTabbedPage.BarIndicatorColorProperty.PropertyName)
{
UpdateBarIndicatorColor();
}
else if (e.PropertyName == TopTabbedPage.SwipeEnabledColorProperty.PropertyName)
{
UpdateSwipe(Tabbed.SwipeEnabled);
}
}
public override UIViewController ChildViewControllerForStatusBarHidden()
{
var current = Tabbed.CurrentPage;
if (current == null)
return null;
return GetViewController(current);
}
void UpdateSwipe(bool swipeEnabled)
{
pageViewController.WeakDataSource = swipeEnabled ? this : null;
}
void Reset()
{
var i = 0;
foreach (var page in Tabbed.Children)
{
SetupPage(page, i++);
}
}
void SetControllers()
{
var list = new List<UIViewController>();
var titles = new List<string>();
for (var i = 0; i < Tabbed.Children.Count; i++)
{
var child = Tabbed.Children[i];
var v = child as VisualElement;
if (v == null)
continue;
var renderer = Platform.GetRenderer(v);
if (renderer == null) continue;
list.Add(renderer.ViewController);
titles.Add(Tabbed.Children[i].Title);
}
ViewControllers = list.ToArray();
TabBar.SetItems(titles);
}
void SetupPage(Page page, int index)
{
IVisualElementRenderer renderer = Platform.GetRenderer(page);
if (renderer == null)
{
renderer = Platform.CreateRenderer(page);
Platform.SetRenderer(page, renderer);
}
page.PropertyChanged -= OnPagePropertyChanged;
page.PropertyChanged += OnPagePropertyChanged;
}
void TeardownPage(Page page, int index)
{
page.PropertyChanged -= OnPagePropertyChanged;
Platform.SetRenderer(page, null);
}
void UpdateBarBackgroundColor()
{
if (Tabbed == null || TabBar == null)
return;
var barBackgroundColor = Tabbed.BarBackgroundColor;
if (!_defaultBarColorSet)
{
_defaultBarColor = TabBar.BackgroundColor;
_defaultBarColorSet = true;
}
TabBar.BackgroundColor = barBackgroundColor.ToUIColor();
}
void UpdateBarTextColor()
{
TabBar.TextColor = Tabbed.BarTextColor.ToUIColor();
}
void UpdateBarIndicatorColor()
{
TabBar.IndicatorColor = Tabbed.BarIndicatorColor.ToUIColor();
}
}
}

ErrorProvider - Change BackColor Instead of Showing Icon

I'm stuck with some legacy code that I want to upgrade a bit. I want to change the way the ErrorProvider shows the error status on a Control. Default behavior is the Icon, and a ToolTip if you hover on the icon.
I would like to change this behavior to be more similar to what we use in our WPF controls. Which is a red back-color(Salmon pink) and the tool-tip on the control itself.
Any tips, links or some way forward
EDIT.
See my answer below, on what i ended up with.
ErrorProvider component doesn't support this feature and if you need it you can create it yourself.
You can subscribe to BindingComplete event of a BindingManagerBase and then you can use the event arg which is of type BindingCompleteEventArgs that contains some useful properties:
ErrorText to determine if there is an error in data-binding
Binding.Control to determine the control which is bounded to
These are enough for us to implement our solution.
Code
Here is a sample code which shows how can you handle BindingComplete event and use it to change BackColor and tool-tip of a control based on it's valid or invalid state.
Suppose you have a binding source, myBindingSource which is bound to a SampleModel class which is implemented IDataErrorInfo. You can subscribe to BindingComplete event of this.BindingContext[this.myBindingSource]:
private void Form1_Load(object sender, EventArgs e)
{
this.myBindingSource.DataSource = new SampleModel();
var bindingManager = this.BindingContext[this.myBindingSource];
bindingManager.BindingComplete += bindingManager_BindingComplete;
}
Dictionary<Control, Color> Items = new Dictionary<Control, Color>();
private void bindingManager_BindingComplete(object sender, BindingCompleteEventArgs e)
{
var control = e.Binding.Control;
//Store Original BackColor
if (!Items.ContainsKey(control))
Items[control] = control.BackColor;
//Check If there is an error
if (!string.IsNullOrEmpty(e.ErrorText))
{
control.BackColor = Color.Salmon;
this.errorToolTip.SetToolTip(control, e.ErrorText);
}
else
{
e.Binding.Control.BackColor = Items[e.Binding.Control];
this.errorToolTip.SetToolTip(control, null);
}
}
Thank you Reza Aghaei. This is what i came up with based on your comment and some additional searching... Some of this code comes from msdn resource
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Linq;
using System.Security.Permissions;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ErrorProvider
{
class BackgroundColorErrorProvider: Component, IExtenderProvider, ISupportInitialize
{
public BackgroundColorErrorProvider()
{
currentChanged = new EventHandler(ErrorManager_CurrentChanged);
}
public BackgroundColorErrorProvider(ContainerControl parentControl)
: this()
{
this.parentControl = parentControl;
propChangedEvent = new EventHandler(ParentControl_BindingContextChanged);
parentControl.BindingContextChanged += propChangedEvent;
}
public BackgroundColorErrorProvider(IContainer container)
: this()
{
if (container == null) {
throw new ArgumentNullException("container");
}
container.Add(this);
}
public bool CanExtend(object extendee)
{
return extendee is Control && !(extendee is Form) && !(extendee is ToolBar);
}
private bool inSetErrorManager = false;
private object dataSource;
private string dataMember = null;
private ContainerControl parentControl;
private BindingManagerBase errorManager;
private bool initializing;
private EventHandler currentChanged;
private EventHandler propChangedEvent;
private Dictionary<Control, Color> originalColor = new Dictionary<Control, Color>();
private Color errorBackgroundColor;
public ContainerControl ContainerControl
{
[UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]
[UIPermission(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)]
get
{
return parentControl;
}
set
{
if (parentControl != value)
{
if (parentControl != null)
parentControl.BindingContextChanged -= propChangedEvent;
parentControl = value;
if (parentControl != null)
parentControl.BindingContextChanged += propChangedEvent;
Set_ErrorManager(this.DataSource, this.DataMember, true);
}
}
}
public string DataMember
{
get { return dataMember; }
set
{
if (value == null) value = "";
Set_ErrorManager(this.DataSource, value, false);
}
}
public object DataSource
{
get { return dataSource; }
set
{
if ( parentControl != null && value != null && String.IsNullOrEmpty(this.dataMember))
{
// Let's check if the datamember exists in the new data source
try
{
errorManager = parentControl.BindingContext[value, this.dataMember];
}
catch (ArgumentException)
{
// The data member doesn't exist in the data source, so set it to null
this.dataMember = "";
}
}
Set_ErrorManager(value, this.DataMember, false);
}
}
public override ISite Site
{
set
{
base.Site = value;
if (value == null)
return;
IDesignerHost host = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
if (host != null)
{
IComponent baseComp = host.RootComponent;
if (baseComp is ContainerControl)
{
this.ContainerControl = (ContainerControl)baseComp;
}
}
}
}
private ToolTip toolTip;
public ToolTip ToolTip
{
get { return toolTip; }
set { toolTip = value; }
}
public Color ErrorBackgroundColor
{
get { return errorBackgroundColor; }
set { errorBackgroundColor = value; }
}
private void Set_ErrorManager(object newDataSource, string newDataMember, bool force)
{
if (inSetErrorManager)
return;
inSetErrorManager = true;
try
{
bool dataSourceChanged = this.DataSource != newDataSource;
bool dataMemberChanged = this.DataMember != newDataMember;
//if nothing changed, then do not do any work
//
if (!dataSourceChanged && !dataMemberChanged && !force)
{
return;
}
// set the dataSource and the dataMember
//
this.dataSource = newDataSource;
this.dataMember = newDataMember;
if (!initializing)
{
UnwireEvents(errorManager);
// get the new errorManager
//
if (parentControl != null && this.dataSource != null && parentControl.BindingContext != null)
{
errorManager = parentControl.BindingContext[this.dataSource, this.dataMember];
}
else
{
errorManager = null;
}
// wire the events
//
WireEvents(errorManager);
// see if there are errors at the current
// item in the list, w/o waiting for the position to change
if (errorManager != null)
UpdateBinding();
}
}
finally
{
inSetErrorManager = false;
}
}
public void UpdateBinding()
{
ErrorManager_CurrentChanged(errorManager, EventArgs.Empty);
}
private void UnwireEvents(BindingManagerBase listManager)
{
if (listManager != null)
{
listManager.CurrentChanged -= currentChanged;
listManager.BindingComplete -= new BindingCompleteEventHandler(this.ErrorManager_BindingComplete);
CurrencyManager currManager = listManager as CurrencyManager;
if (currManager != null)
{
currManager.ItemChanged -= new ItemChangedEventHandler(this.ErrorManager_ItemChanged);
currManager.Bindings.CollectionChanged -= new CollectionChangeEventHandler(this.ErrorManager_BindingsChanged);
}
}
}
private void WireEvents(BindingManagerBase listManager)
{
if (listManager != null)
{
listManager.CurrentChanged += currentChanged;
listManager.BindingComplete += new BindingCompleteEventHandler(this.ErrorManager_BindingComplete);
CurrencyManager currManager = listManager as CurrencyManager;
if (currManager != null)
{
currManager.ItemChanged += new ItemChangedEventHandler(this.ErrorManager_ItemChanged);
currManager.Bindings.CollectionChanged += new CollectionChangeEventHandler(this.ErrorManager_BindingsChanged);
}
}
}
private void ErrorManager_BindingsChanged(object sender, CollectionChangeEventArgs e)
{
ErrorManager_CurrentChanged(errorManager, e);
}
private void ParentControl_BindingContextChanged(object sender, EventArgs e)
{
Set_ErrorManager(this.DataSource, this.DataMember, true);
}
private void ErrorManager_ItemChanged(object sender, ItemChangedEventArgs e)
{
BindingsCollection errBindings = errorManager.Bindings;
int bindingsCount = errBindings.Count;
// If the list became empty then reset the errors
if (e.Index == -1 && errorManager.Count == 0)
{
for (int j = 0; j < bindingsCount; j++)
{
if ((errBindings[j].Control != null))
{
// ...ignore everything but bindings to Controls
SetError(errBindings[j].Control, "");
}
}
}
else
{
ErrorManager_CurrentChanged(sender, e);
}
}
private void SetError(Control control, string p)
{
if (String.IsNullOrEmpty(p))
{
if (originalColor.ContainsKey(control))
control.BackColor = originalColor[control];
toolTip.SetToolTip(control, null);
}
else
{
control.BackColor = ErrorBackgroundColor;
toolTip.SetToolTip(control, p);
}
}
private void ErrorManager_BindingComplete(object sender, BindingCompleteEventArgs e)
{
Binding binding = e.Binding;
if (binding != null && binding.Control != null)
{
SetError(binding.Control, (e.ErrorText == null ? String.Empty : e.ErrorText));
}
}
private void ErrorManager_CurrentChanged(object sender, EventArgs e)
{
if (errorManager.Count == 0)
{
return;
}
object value = errorManager.Current;
if (!(value is IDataErrorInfo))
{
return;
}
BindingsCollection errBindings = errorManager.Bindings;
int bindingsCount = errBindings.Count;
// We can only show one error per control, so we will build up a string...
//
Hashtable controlError = new Hashtable(bindingsCount);
for (int j = 0; j < bindingsCount; j++)
{
// Ignore everything but bindings to Controls
if (errBindings[j].Control == null)
{
continue;
}
string error = ((IDataErrorInfo)value)[errBindings[j].BindingMemberInfo.BindingField];
if (error == null)
{
error = "";
}
string outputError = "";
if (controlError.Contains(errBindings[j].Control))
outputError = (string)controlError[errBindings[j].Control];
// VSWhidbey 106890: Utilize the error string without including the field name.
if (String.IsNullOrEmpty(outputError))
{
outputError = error;
}
else
{
outputError = string.Concat(outputError, "\r\n", error);
}
controlError[errBindings[j].Control] = outputError;
}
IEnumerator enumerator = controlError.GetEnumerator();
while (enumerator.MoveNext())
{
DictionaryEntry entry = (DictionaryEntry)enumerator.Current;
SetError((Control)entry.Key, (string)entry.Value);
}
}
public void BeginInit()
{
initializing = true;
}
public void EndInit()
{
initializing = false;
Set_ErrorManager(this.DataSource, this.DataMember, true);
}
}
}

Set tooltip on range of text in wpf richtextbox

I am trying to set a tooltip on an arbitrary range of text on a richtextbox. Is this possible? If so how would I do it e.g by passing in parameters "from" and "to" as (int) indexes.
Thanks
You could use the following as a starting point:
Add a reference to System.Windows.Interactivity.
Add the following classes to your project:
public class TextRangeToolTip
{
public int StartPosition { get; set; }
public int Length { get; set; }
public object ToolTip { get; set; }
internal bool IsInRange(int position)
{
return this.StartPosition <= position && position < this.StartPosition + this.Length;
}
}
public class TextRangeToolTipCollection : ObservableCollection<TextRangeToolTip> {}
[ContentProperty("Ranges")]
public class ToolTipBehavior : Behavior<RichTextBox>
{
private const int ToolTipHideMouseDelta = 9;
public static readonly DependencyProperty RangesProperty
= DependencyProperty.Register("Ranges", typeof(TextRangeToolTipCollection),
typeof (ToolTipBehavior),
new PropertyMetadata(OnRangesChanged));
private readonly DispatcherTimer timer;
private readonly ToolTip toolTip;
private Point lastMousePosition;
public TextRangeToolTipCollection Ranges
{
get
{
return (TextRangeToolTipCollection)this.GetValue(RangesProperty)
?? (this.Ranges = new TextRangeToolTipCollection());
}
set { this.SetValue(RangesProperty, value); }
}
public ToolTipBehavior()
{
this.Ranges = new TextRangeToolTipCollection();
this.timer = new DispatcherTimer();
this.timer.Tick += this.TimerOnTick;
this.timer.Interval = TimeSpan.FromSeconds(1);
this.toolTip = new ToolTip {Placement = PlacementMode.Relative};
}
protected override void OnAttached()
{
this.AssociatedObject.ToolTip = this.toolTip;
this.toolTip.PlacementTarget = this.AssociatedObject;
ToolTipService.SetIsEnabled(this.AssociatedObject, false);
this.AssociatedObject.MouseMove += this.AssociatedObjectOnMouseMove;
}
protected override void OnDetaching()
{
this.timer.Stop();
this.toolTip.PlacementTarget = null;
this.AssociatedObject.ToolTip = null;
this.AssociatedObject.ClearValue(ToolTipService.IsEnabledProperty);
this.AssociatedObject.MouseMove -= this.AssociatedObjectOnMouseMove;
}
private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
{
Point currentMousePosition = mouseEventArgs.GetPosition(this.AssociatedObject);
if (this.AssociatedObject.IsMouseCaptured)
{
Vector delta = currentMousePosition
- this.lastMousePosition;
if (delta.X*delta.X + delta.Y*delta.Y <= ToolTipHideMouseDelta)
{
this.toolTip.HorizontalOffset = currentMousePosition.X + 10;
this.toolTip.VerticalOffset = currentMousePosition.Y + 10;
return;
}
this.AssociatedObject.ReleaseMouseCapture();
this.toolTip.IsOpen = false;
}
if (this.AssociatedObject.IsMouseOver)
{
this.lastMousePosition = currentMousePosition;
this.timer.Stop();
this.timer.Start();
}
}
private static void OnRangesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
((ToolTipBehavior) d).OnRangesChanged((IEnumerable<TextRangeToolTip>) e.OldValue,
(IEnumerable<TextRangeToolTip>) e.NewValue);
}
private void OnRangesChanged(IEnumerable<TextRangeToolTip> oldRanges, IEnumerable<TextRangeToolTip> newRanges)
{
var oldObservable = oldRanges as INotifyCollectionChanged;
if (oldObservable != null)
{
CollectionChangedEventManager.RemoveHandler(oldObservable, this.OnRangesCollectionChanged);
}
var newObservable = newRanges as INotifyCollectionChanged;
if (newObservable != null)
{
CollectionChangedEventManager.AddHandler(newObservable, this.OnRangesCollectionChanged);
}
this.UpdateToolTip();
}
private void OnRangesCollectionChanged(
object sender,
NotifyCollectionChangedEventArgs notifyCollectionChangedEventArgs)
{
this.UpdateToolTip();
}
private bool SetToolTipData()
{
if (this.Ranges == null)
{
return false;
}
TextPointer pointer = this.AssociatedObject.GetPositionFromPoint(this.lastMousePosition, false);
if (pointer == null)
{
return false;
}
int position = this.AssociatedObject.Document.ContentStart.GetOffsetToPosition(pointer);
TextRangeToolTip matchingRange = this.Ranges.FirstOrDefault(r => r.IsInRange(position));
if (matchingRange == null)
{
return false;
}
this.toolTip.Content = matchingRange.ToolTip;
return true;
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
this.timer.Stop();
if (this.AssociatedObject.IsMouseOver && this.SetToolTipData())
{
this.toolTip.IsOpen = true;
this.AssociatedObject.CaptureMouse();
}
}
private void UpdateToolTip()
{
if (this.AssociatedObject != null && this.AssociatedObject.IsMouseCaptured && !this.SetToolTipData())
{
this.toolTip.IsOpen = false;
this.AssociatedObject.ReleaseMouseCapture();
}
}
}
Use it on your RichTextBox like this:
<RichTextBox>
<i:Interaction.Behaviors>
<myapp:ToolTipBehavior>
<myapp:TextRangeToolTip StartPosition="10" Length="4" ToolTip="some" />
<myapp:TextRangeToolTip StartPosition="15" Length="4" ToolTip="text" />
</myapp:ToolTipBehavior>
</i:Interaction.Behaviors>
<FlowDocument>
<Paragraph>This is some text. This is some other text.</Paragraph>
</FlowDocument>
</RichTextBox>
Alternatively, you can bind a TextRangeToolTipCollection to the Ranges property like this:
<RichTextBox Document="{Binding Document}">
<i:Interaction.Behaviors>
<myapp:ToolTipBehavior Ranges="{Binding RangeToolTips}" />
</i:Interaction.Behaviors>
</RichTextBox>
Getting the positions right is a bit tricky, because WPF counts symbols, not characters. You could extend the TextRangeToolTip class to have properties of type TextPointer or TextRange and construct it using your FlowDocument instance.

NavigationService navigates to non-existing object when GoBack() is called

I am working on a WPF web application with a MainPage which is using ninject to load pages.
Basically I am woundering if there is a way to tell NavigationService that an Id has changed because a user updated a value in a composite key.
I'll do my best to explain a little more. My MultiTagPage has a MultiTagViewModel and it shows a multitagvalue consisting of (MultiTagDef, Key, Value). There is also a DataGrid with other values with the same key and MultiTagDef. If you dubble click on one of those values the corresponding multitagvalue is showed instead.
In the database the multitagvalues are stored with composite keys (Multitagdef.Name, key, value). So if somebody updates a multitagvalue the Id is changed (say from (A, B, C) to (A, B, D)) and saved, then if the user proceeds to another multitagvalue in the datagrid (A, B, E) and perhaps deletes that object then the navigationservice try to load (A, B, C) instead of (A, B, D).
The architecture is designed for objects which has an ID column which, of course, never changes. Unfortunately adding an ID column is not an option in this case. So does anyone have a suggestion of how to solve this? Should I try to reload the page everytime somebody saves or could I tell the NavigationService that the current object now has changed ID?
Now, code:
From MainPage:
public partial class MainPage : IUIService
{
public static readonly DependencyProperty MainModelProperty = PropertyHelper.Register<MainPage>(x => x.MainModel);
public MainModel MainModel
{
get { return (MainModel)GetValue(MainModelProperty); }
set { SetValue(MainModelProperty, value); }
}
private static readonly ILog log = LogManager.GetLogger(typeof(MainPage));
public MainPage()
{
// Make doubly sure...
ShowsNavigationUI = false;
InitializeComponent();
App.Kernel.Rebind<IUIService>().ToConstant(this);
MainModel = App.Kernel.Get<MainModel>();
WindowTitle = MainModel.Title;
ContentFrame.Navigating += Navigating;
ContentFrame.Navigated += Navigated;
ContentFrame.NavigationFailed += NavigationFailed;
}
private void Navigating(object sender, NavigatingCancelEventArgs args)
{
object dataContext = null;
if(ContentFrame.Content is FrameworkElement) {
dataContext = ((FrameworkElement)ContentFrame.Content).DataContext;
} else if(ContentFrame.Content is FrameworkContentElement) {
dataContext = ((FrameworkContentElement)ContentFrame.Content).DataContext;
}
if(dataContext is ISaveable && ((ISaveable)dataContext).NeedsSave) {
if(MessageControl.UnsavedSync() != MessageControl.Button.Yes) {
args.Cancel = true;
}
}
}
private void Navigated(object sender, NavigationEventArgs e)
{
var mi = e.ExtraData as MenuItemModel;
if(mi == null) {
var page = e.Content as IMenuItemPage;
if(page != null) {
mi = page.MenuItem;
}
if(mi == null) {
log.DebugFormat("Navigated to {0} ({1}) without menu item", e.Content, e.Uri);
return;
}
}
MainModel.CurrentMenuItem = mi;
if(mi.Type != MenuItemType.Folder) {
Settings.Default.AddRecentMenuItem(new RecentMenuItem(mi.MenuItem));
}
}
#region Generic Edit command
private void EditCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.Handled = true;
e.CanExecute = false;
var param = Unwrap(e.Parameter);
var paramType = GetEditType(param);
if(paramType == null || !editPages.ContainsKey(paramType)) {
return;
}
e.CanExecute = ToConstructorArgument(param) != null;
}
private void EditExecuted(object sender, ExecutedRoutedEventArgs e)
{
Edit(e.Parameter);
}
private void Edit(object param)
{
var paramType = GetEditType(param);
if(paramType == null || !editPages.ContainsKey(paramType)) {
log.WarnFormat("Page for param {0} (type {1}) not found", param, paramType);
return;
}
if(param is IList) {
var list = (IList)param;
if(list.Count > 1000) {
Show("Too many items selected", "Please select no more than 1000 items at a time", messageTheme: MessageTheme.Warning);
return;
}
}
var arg = ToConstructorArgument(param);
if(arg == null) {
log.Warn("Unexpected parameter " + param + " supplied to EditExecuted");
return;
}
var pageType = editPages[paramType];
try {
log.DebugFormat("Got a parameter of type {0}, navigating to edit page {1}", param.GetType(), pageType);
Navigate(MakePage(pageType, arg));
} catch(Exception ex) {
log.Error("Unable to load edit page for parameter " + param, ex);
}
}
private static Page MakePage(Type pageType, params IParameter[] p)
{
var page = (Page)App.Kernel.Get(pageType, p);
var dp = ClientUtil.GetViewModelProperty(page.GetType());
if(dp != null) {
page.Loaded += (o, args) => {
var skrap = App.Kernel.Get(dp.PropertyType, p);
page.SetValue(dp, App.Kernel.Get(dp.PropertyType, p));
};
page.Unloaded += (o, args) => {
try {
page.ClearValue(dp);
} catch(Exception e) {
// Often happens when datagrid is in edit mode when navigating away from page:
// http://connect.microsoft.com/VisualStudio/feedback/details/571967/wpf-datagrid-causes-crash-with-sorting-is-not-allowed-during-an-addnew-or-edititem-transaction
log.Warn("Error while unloading page", e);
}
};
ViewModelBehavior.SetUpdateUIError(page, true);
}
return page;
}
#endregion
#region Navigate command
private void NavigateCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = e.Parameter is Type;
e.Handled = true;
}
private void NavigateExecuted(object sender, ExecutedRoutedEventArgs e)
{
var type = e.Parameter as Type;
if(type == null) {
return;
}
Navigate(MakePage(type));
e.Handled = true;
}
#endregion
#region IUIService implementation
public void Navigate(Type type, params Tuple<string, object>[] parameters)
{
Navigate(MakePage(type, parameters.Select(x => new ConstructorArgument(x.Item1, x.Item2)).ToArray()));
}
public void Navigate(Type type, MenuItemModel menuItem, params Tuple<string, object>[] parameters)
{
Navigate(MakePage(type, parameters.Select(x => new ConstructorArgument(x.Item1, x.Item2))
.Prepend(new ConstructorArgument("menuItem", menuItem))
.Prepend(new ConstructorArgument("props", menuItem.Params))
.ToArray()),
menuItem);
}
public void Navigate(Page content, object extraData = null)
{
if(ContentFrame != null) {
if(ContentFrame.Content is DependencyObject) {
foreach(var dg in WpfUtil.FindDescendants<DataGrid>((DependencyObject)ContentFrame.Content)) {
while(!dg.CommitEdit()) { /* Keep committing */ }
}
}
ContentFrame.Navigate(content, extraData);
}
}
public bool NavigateBack()
{
if(ContentFrame != null && ContentFrame.CanGoBack) {
ContentFrame.GoBack();
return true;
}
if(NavigationService != null && NavigationService.CanGoBack) {
NavigationService.GoBack();
return true;
}
return false;
}
}
Please tell me if you need more information.

Categories

Resources