I have gridView with 3 columns. One column has repositoryItempictureEdit with 4 EditorButtons
this.repActionsBtn.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
new DevExpress.XtraEditors.Controls.EditorButton(),
new DevExpress.XtraEditors.Controls.EditorButton(),
new DevExpress.XtraEditors.Controls.EditorButton(),
new DevExpress.XtraEditors.Controls.EditorButton()});
And i have a buttonClick event handler
private void repActionsBtn_ButtonClick(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
{
ButtonEdit editor = sender as ButtonEdit;
if (editor != null)
{
object obj = this.mainView.GetFocusedRow();
int id = GetValueFromAnonymousType<int>(obj, "ID");
//undo
if (e.Button == editor.Properties.Buttons[0])
{
_ignoredIds.Remove(id);
}
//delete
else if (e.Button == editor.Properties.Buttons[1])
{
//HERE i want change visibility buttons
e.Button.Visibility = false;
_ignoredIds.Add(id);
}
//edit
else if (e.Button == editor.Properties.Buttons[2])
{
_storedIds.Clear();
_storedIds.Add(id);
this.DialogResult = System.Windows.Forms.DialogResult.Retry;
}
//save
else if (e.Button == editor.Properties.Buttons[3])
{
//save
_storedIds.Remove(id);
}
mainView.RefreshRow(this.mainView.FocusedRowHandle);
}
}
But fires redraw and i get default repositoryItemButtonEdit with buttons is visible.
How i can change visibility(or property Enabled) of EditorButtons by user actions. (For each row)?
Devexpress support give me a solution. Here you can find the solution and download test project.
Related
I am using a DevExpress TreeList. I have two methods MouseDown() and MouseUP() to get the item from the treelist by right click and then show a contextmenu/popup menu with changes to it at runtime.
Problem: ContextMenu or PopupMenu displays the barSubItem3.Enabled = false;change on the next click. Not on the current click.
private void TreeList1_MouseDown(object sender, MouseEventArgs e)
{
TreeList tree = sender as TreeList;
if (e.Button == MouseButtons.Right && ModifierKeys == Keys.None
&& tree.State == TreeListState.Regular)
{
Point pt = tree.PointToClient(MousePosition);
TreeListHitInfo info = tree.CalcHitInfo(pt);
if (info.HitInfoType == HitInfoType.Cell)
{
SavedFocused = new TreeListNode();
SavedFocused = tree.FocusedNode;
tree.FocusedNode = info.Node;
/* get value from node that is clicked by column index */
switch (SavedFocused.GetValue(0).ToString())
{
case "A":
barSubItem3.Enabled = false;
break;
case "B":
barSubItem3.Enabled = true;
break;
}
}
}
}
private void TreeList1_MouseUp1(object sender, MouseEventArgs e)
{
TreeList tree = sender as TreeList;
if (e.Button == MouseButtons.Right && ModifierKeys == Keys.None
&& tree.State == TreeListState.Regular)
{
popUpMenu.ShowPopup(MousePosition);
}
}
I guess that's happening because you're actually modifying the state of the item once it's already being shown.
Use the PopupMenuShowing event instead. Here is an example on how to modify the PopUpMenu using a GridView.
private void Whatever_PopupMenuShowing(object sender, DevExpress.XtraGrid.Views.Grid.PopupMenuShowingEventArgs e)
{
var menu = e.Menu;
var hi = e.HitInfo;
if (!(sender is GridView view))
return;
var inDetails = (hi.HitTest == GridHitTest.EmptyRow);
if (menu == null && inDetails)
{
menu = new DevExpress.XtraGrid.Menu.GridViewMenu(view);
e.Menu = menu;
}
if (menu == null)
return;
//If there are any entries, show "Duplicate" button
var rowHandle = hi.RowHandle;
if (!view.IsDataRow(rowHandle)) return;
var mnuDuplicate = new DXMenuItem("Duplicate",
async delegate { await ClickDuplicate(); },
Properties.Resources.copy_16x16)
{
BeginGroup = true
};
menu.Items.Add(mnuDuplicate);
}
In my application, I have a form with two panels. Inside one panel is a button. Inside the other is a DevExpress Grid control. The grid is made up of 3 columns. You can drag values from one column into the other to copy it.
My problem is that whenever I do a drag-and-drop from one column to another, the focus on the application goes into an unusual state. The grid remains focused; I can mouse over the headers and see them react as normal. However the rest of the application is not focused. Mouse over the button in the other panel does not react, nor do the menus or form controls. If I click on the button, it reacts like I clicked on an unfocused application. I have to click again to actually activate the button. Same for every control except the grid.
I have tried using Activate() and Focus() on the button and form but to no avail.
namespace Company.StuffUploader
{
public partial class ComputationGrid : DevExpress.XtraEditors.XtraUserControl
{
private BindingList<ComputationLinkModel> _links = new BindingList<ComputationLinkModel>();
public List<ComputationLinkModel> ComputationLinkModels
{
get
{
return new List<ComputationLinkModel>(_links);
}
}
public ComputationGrid()
{
InitializeComponent();
}
private void ComputationGrid_Load(object sender, EventArgs e)
{
_gridControl.DataSource = _links;
}
private DragDropEffects GetDragEffect(DragEventArgs e)
{
var text = e.Data.GetData("System.String") as string;
if (text == null)
return DragDropEffects.None;
var link = GetLinkFromScreenPoint(new Point(e.X, e.Y));
if (link == null)
return DragDropEffects.None;
var tokens = text.Split('\t');
if (tokens.Count() != 2)
return DragDropEffects.None;
var dateString = link.movedate.ToString("yyyy-MM-dd");
if (link.StuffSurfaceName == tokens[0] && dateString != tokens[1])
return DragDropEffects.Move;
else
return DragDropEffects.None;
}
private ComputationLinkModel GetLinkFromScreenPoint(Point screenPt)
{
var pt = _gridControl.PointToClient(screenPt);
var hitInfo = _gridView.CalcHitInfo(pt);
return _gridView.GetRow(hitInfo.RowHandle) as ComputationLinkModel;
}
private void _gridControl_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
var hitInfo = _gridView.CalcHitInfo(e.Location);
if (hitInfo == null || !hitInfo.InRowCell)
return;
// Only allow dragging from target column
if (hitInfo.Column.AbsoluteIndex != 0)
return;
var link = _gridView.GetRow(hitInfo.RowHandle) as ComputationLinkModel;
if (link == null)
return;
var item = string.Format("{0}\t{1}", link.StuffSurfaceName, link.movedate.ToString("yyyy-MM-dd"));
DoDragDrop(item, DragDropEffects.Move);
}
}
private void _gridControl_DragOver(object sender, DragEventArgs e)
{
e.Effect = GetDragEffect(e);
}
private void _gridControl_DragDrop(object sender, DragEventArgs e)
{
}
private void _gridControl_DragEnter(object sender, DragEventArgs e)
{
e.Effect = GetDragEffect(e);
}
private void _unlinkButton_Click(object sender, EventArgs e)
{
}
}
}
I figured out my own problem. Calling DoDragDrop() from within MouseDown event does not seem to work correctly. The proper way is to call it from MouseMove(). The documentation on MSDN hints at this in its example code.
Ensure that you set the DXMouseEventArgs.Handled property to true in the GridView's Mouse~ event handlers. It guarantees that default handling of these events will be prohibited. Review this example to see how to do this.
i'm just new to c# and visual studio
so i figured how to mask the password in my datagridview with this
private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (e.ColumnIndex == 5 && e.Value != null)
{
dataGridView.Rows[e.RowIndex].Tag = e.Value;
e.Value = new String('\u25CF', e.Value.ToString().Length);
}
}
Now i wanted to show the password again when i click on the cell, i figured it would be on dataGridView_CellClick event but i can't figure how to make it show up again. do i assign it to e.Value again?
use a textbox by design in that column of gridview and from source add a checkbox too !
then use this code
private void FromSourceAddedCheckBox_CheckedChanged(object sender, EventArgs e)
{
if (FromSourceAddedCheckBox.Checked == true)
{
GridviewTextboxID.UseSystemPasswordChar = true;
}
else
{
GridviewTextboxID.UseSystemPasswordChar = false;
}
}
Does anyone knows how can I validate if the event is raised because the DragAction changed to cancel, or because it actually object was dragged out from the control?
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.dragleave.aspx
[edit]
In this part I start the drag in the object being dragged.
void control_MouseDown(object sender, MouseEventArgs e)
{
var wasClicked = WasClicked;
if (wasClicked != null)
{
WasClicked(this, EventArgs.Empty);
}
// Select this UC on click.
if (IsSelected == false)
IsSelected = true;
else
IsSelected = false;
if (IsSelected == true)
{
_beingDragged = true;
DoDragDrop(this, DragDropEffects.Move);
}
return;
}
This part the event validates when the object being dragged leaves the FlowLayoutPanel.
private void LocationControl_DragLeave(object sender, EventArgs e)
{
foreach (Control c in Controls)
{
if (((PersonDragDrop)c).beingDragged == true)
{
((PersonDragDrop)c).LeaveLocation();
DeletePerson((PersonDragDrop)c);
}
}
}
I have a DataGridView and a context menu that opens when you right click a specific column.
What shows up in the context menu is dependant on what's in the field clicked on - paths to multiple files (the paths are manipulated to create a full UNC path to the correct file).
The only problem is that I can't get the click working.
I did not drag and drop the context menu from the toolbar, I created it programmically.
I figured that if I can get the path (let's call it ContextMenuChosen) to show up in MessageBox.Show(ContextMenuChosen); I could set the same to System.Diagnostics.Process.Start(ContextMenuChosen);
The Mydgv_MouseUp event below actually works to the point where I can get it to fire off MessageBox.Show("foo!"); when something in the context menu is selected but that's where it ends. I left in a bunch of comments below showing what I've tried when it one of the paths are clicked. Some result in empty strings, others error (Object not set to an instance...).
I searched code all day yesterday but couldn't find another way to hook up a dynamically built Context Menu clickEvent.
Code and comments:
ContextMenu m = new ContextMenu();
// SHOW THE RIGHT CLICK MENU
private void Mydgv_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
int currentMouseOverCol = Mydgv.HitTest(e.X, e.Y).ColumnIndex;
int currentMouseOverRow = Mydgv.HitTest(e.X, e.Y).RowIndex;
if (currentMouseOverRow >= 0 && currentMouseOverCol == 6)
{
string[] paths = myPaths.Split(';');
foreach (string path in paths)
{
string UNCPath = "\\\\1.1.1.1\\c$\\MyPath\\";
string FilePath = path.Replace("c:\\MyPath\\", #"");
m.MenuItems.Add(new MenuItem(UNCPath + FilePath));
}
}
m.Show(Mydgv, new Point(e.X, e.Y));
}
}
// SELECTING SOMETHING IN THE RIGHT CLICK MENU
private void Mydgv_MouseUp(object sender, MouseEventArgs e)
{
DataGridView.HitTestInfo hitTestInfo;
if (e.Button == MouseButtons.Right)
{
hitTestInfo = Mydgv.HitTest(e.X, e.Y);
// If column is first column
if (hitTestInfo.Type == DataGridViewHitTestType.Cell && hitTestInfo.ColumnIndex == 6)
{
//MessageBox.Show(m.ToString());
////MessageBox.Show(m.Tag.ToString());
//MessageBox.Show(m.Name.ToString());
//MessageBox.Show(m.MenuItems.ToString());
////MessageBox.Show(m.MdiListItem.ToString());
// MessageBox.Show(m.Name);
//if (m.MenuItems.Count > 0)
//MessageBox.Show(m.MdiListItem.Text);
//MessageBox.Show(m.ToString());
//MessageBox.Show(m.MenuItems.ToString());
//Mydgv.ContextMenu.Show(m.Name.ToString());
//MessageBox.Show(ContextMenu.ToString());
//MessageBox.Show(ContextMenu.MenuItems.ToString());
//MenuItem.text
//MessageBox.Show(this.ContextMenu.MenuItems.ToString());
}
m.MenuItems.Clear();
}
}
I'm very close to completing this so any help would be much appreciated.
I don't see an event handler wired to your menu item, so that something will happen when you click it:
void menu_Click(object sender, EventArgs e) {
MessageBox.Show(((MenuItem)sender).Text);
}
Then attach it when you add the menu item to the context menu:
MenuItem mi = new MenuItem(UNCPath + FilePath);
mi.Click += menu_Click;
m.MenuItems.Add(mi);
You may handle CellMouseDown like this when you when you right click a cell of a specific column. The specific column is achieved by e.ColumnIndex check
Aditionally, you can use GetCellDisplayRectangle instead of hittest
ContextMenu cm = new ContextMenu();
void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
if (e.ColumnIndex == 0)
{
cm.MenuItems.Clear();
var mi = new MenuItem("C:\temp");
mi.MenuItems.Add(mi);
// handle menu item click event here [as required]
mi.Click += OnMenuItemClick;
cm.MenuItems.Add(0, mi);
var bounds = dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, false);
if (sender != null)
{
cm.Show(sender as DataGridView, new Point(bounds.X, bounds.Y));
}
}
}
}
void OnMenuItemClick(object sender, EventArgs e)
{
MessageBox.Show(((MenuItem)sender).Text);
}