I am using a DataRepeater control to show a popup. I am able to set BackColor of the current item by this code
private void dataRepeater1_CurrentItemIndexChanged(object sender, EventArgs e)
{
dataRepeater1.CurrentItem.BackColor = Color.Red;
}
but I am unable to add BackColor white for the previous item. Also I want to change the BackColor of the item form the list I am hovering mouse.
One way to solve this is to have one more property in your class, maybe called DataRepeater1_PreviousItem:
class YourClass
{
DataRepeaterItem DataRepeater1_PreviousItem { get; set; }
// ... some other code
private void dataRepeater1_CurrentItemIndexChanged(object sender, EventArgs e)
{
if (DataRepeater1_PreviousItem != null)
DataRepeater1_PreviousItem.BackColor = Color.White;
dataRepeater1.CurrentItem.BackColor = Color.Red;
DataRepeater1_PreviousItem = dataRepeater1.CurrentItem;
}
}
Related
I have two forms; one of them is containing listview, and another one is just a form.
I want to make a thing :
If I drag an item in listview to a Form, a messagebox would be pop up.
and the message would be text of the item.
However I don't know why 'SelectedItem' is null. When I trace the SelectedItem, it was null.
I found I have to use MouseDown and DragDrop events, but I have no idea how to use.
First one is the listview's code :
rListCtrl.MouseDown += rListCtrl_MouseDown;
rListCtrl.DragDrop += rListCtrl_DragDrop;
private void rListCtrl_MouseDown(object sender, MouseEventArgs e)
{
StringBuilder sb = new STringBuilder();
sb.Append(radListView1.SelectedItem.ToString());
testName = sb.ToString();
}
private void rListCtrl_DragDrop(object sender, DragEventArgs e){
{
MessageBox.Show(testName);
}
radListView1 is the name of listview.
The reason why SelectedItem is null, is that the Item only gets selected when you actually perform a click, not a mere MouseDown.
You can, however, use the IndexFromPoint method to get the Item the mouse had been placed on when the MouseDown Event was evoked:
private void radListView1_MouseDown(object sender, MouseEventArgs e)
{
int index = radListView1.IndexFromPoint(e.Location);
radListView1.SelectedIndex = index;
testName = radListView1.Items[index].ToString();
}
private void rListCtrl_DragDrop(object sender, DragEventArgs e){
{
MessageBox.Show(testName);
}
Form1:
public partial class Form1 : Form
{
Form2 f = new Form2();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
f.Show();
}
private void Form1_MouseEnter(object sender, EventArgs e)
{
if(f.data!= string.Empty)
{
MessageBox.Show(f.data);
f.data = string.Empty;
}
}
}
Form2:
public partial class Form2 : Form
{
public string data = string.Empty;
public Form2()
{
InitializeComponent();
listView1.ItemDrag += doDaragItem;
}
private void doDaragItem(Object sender, ItemDragEventArgs e)
{
data = e.Item.ToString();
}
}
Ron,
RadListView from the Telerik UI from WinForms suite handles the whole drag and drop operation by its ListViewDragDropService. Its PreviewDragOver event allows you to control on what targets the item(s) being dragged can be dropped on. The PreviewDragDrop event allows you to get a handle on all the aspects of the drag and drop operation, the source (drag) list view, the destination (target) control, as well as the item being dragged. Additional information is available in the following help article: https://docs.telerik.com/devtools/winforms/controls/listview/drag-and-drop/listviewdragdropservice
https://docs.telerik.com/devtools/winforms/controls/listview/drag-and-drop/drag-and-drop-using-raddragdropservice
You can also combine the RadDragDropService and OLE drag-and-drop functionality: https://docs.telerik.com/devtools/winforms/controls/listview/drag-and-drop/combining-raddragdropservice-and-ole-drag-and-drop
As to the specific code snippet, indeed, if you don't have a selected item in RadListView, the code in the MouseDown event won't extract the item's text. You need to get the element under the mouse and set the item as selected:
private void radListView1_MouseDown(object sender, MouseEventArgs e)
{
SimpleListViewVisualItem elementUnderMouse = this.radListView1.ElementTree.GetElementAtPoint(e.Location) as SimpleListViewVisualItem;
if (elementUnderMouse != null)
{
this.radListView1.SelectedItem = elementUnderMouse.Data ;
}
StringBuilder sb = new StringBuilder();
sb.Append(radListView1.SelectedItem.Text.ToString());
{
testName = sb.ToString();
}
MessageBox.Show(testName);
}
I hope this information helps.
The project I am working on needs a couple buttons on multiple forms, instead of doing the code shown below I was hoping it could be made global.
This is only one part of the project, all the code does is enlarge the button picture when the user hovers over it.
I've tried looking at classes, tags and attributes. I know classes can be made to use across multiple forms but I cant find out if they work with events.
private void btnEnter_MouseEnter(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Size = new Size(299, 102);
}
private void btnLeave_MouseLeave(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Size = new Size(289, 92);
}
You can create an inherited button. Add a new class then make sure you put : Button after the class name.
using System.Drawing;
using System.Windows.Forms;
namespace InheritedButton
{
public class ExpandButton : Button
{
public Size EnterSize { get; set; }
private Size _LeaveSize;
public Size LeaveSize
{
get
{
return (_LeaveSize);
}
set
{
_LeaveSize = value;
this.Size = LeaveSize;
}
}
public ExpandButton() : base()
{
}
protected override void OnMouseEnter(EventArgs e)
{
this.Size = EnterSize;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
this.Size = LeaveSize;
base.OnMouseLeave(e);
}
}
}
Build your project and the new button will appear in the toolbox. Drop it onto a form/control and make sure you set the EnterSize and LeaveSize. EnterSize determines the size of the button when you mouse over and LeaveSize sets the initial size and sets the size of the button when you mouse out. You don't need to set the Size property, just set LeaveSize.
Any time you want to use the expanding/contracting button just use the inherited one instead.
When I change the font of the whole Form with this code:
this.Font = new Font("Gravity", 12, FontStyle.Bold);
Then all my PictureBoxes (with a size of 16x16) are getting bigger, too.
Is there a way to stop this?
If you insist on changing the font of the form, then use
Control.OnFontChanged Method (EventArgs)
This method will be executed every time you change the font of the form, so when it is executed, you can specify that your PictureBox (All) will keep the font you have defined.
This is if all your PictureBox have the same font:
public class Form1 : Form
{
private void Form1_Load(object sender, EventArgs e)
{
}
protected override OnFontChanged(EventArgs e)
{
foreach(Control control in this.Controls)
{
if(control is PictureBox)
{
control.Font = new Font(<Your constant defined font>);;
}
}
}
}
Now, assuming your pictureboxes have different fonts.
You can store the sources in a list (or also in an array), and each time the source of your form is altered, you simply call the previously stored sources to be reassigned to each PictureBox:
public class Form1 : Form
{
private List<Font> PBFonts = new List<Font>();
private void Form1_Load(object sender, EventArgs e)
{
foreach(Control control in this.Controls)
{
if(control is PictureBox)
{
this.PBFonts.Add(control.Font);
}
}
}
protected override OnFontChanged(EventArgs e)
{
int index = 0;
foreach(Control control in this.Controls)
{
if(control is PictureBox picture)
{
picture.Font = this.PBFonts[index];
}
index++;
}
}
}
I'm working on a class, let's call it MyDataGridView, derived from DataGridView that must be synchronized with the Excel file (i.e. when something changes in the DataGridView, I need to make the same changes to the Excel file).
To detect changes in the DataGridView I use events (for example, RowsAdded, ColumnRemoved, CellValueChanged, etc). But I have a problem with detecting cell whose BackColor have been changed.
The color is changed by the other programmer who uses my class. To do this, he can use the following code:
MyDataGridView myDataGridView;
// create and fill MyDataGridView...
myDataGridView.Rows[0].Cells[0].Style.BackColor = Color.AliceBlue;
My goal is to detect changes of BackColor property to change the Excel file.
To achieve this goal, I (unsuccessfully) tried to use several methods:
CellStyleContentChanged event (problem: can't get the Cell itself from the event handler).
CellFormatting event (problems: event rises so many times and I can't get the reason of its occurrence).
CellStyleChanged event (problem: event only occurs when the Style property changes, but not Style.BackColor).
overriding of DataGridViewCellStyle class (problem: I don't know how to correctly override this class and whether it is possible at all).
Code snippet that will help to reproduce my attempts:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.CellStyleContentChanged += dataGridView1_CellStyleContentChanged;
dataGridView1.CellFormatting += dataGridView1_CellFormatting;
}
// Goal
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.Columns.Add("column1", "column1");
dataGridView1.Columns.Add("column2", "column2");
dataGridView1.Rows.Add("cell1", "cell2");
// how to detect this?
dataGridView1.Rows[0].Cells[0].Style.BackColor = Color.AliceBlue;
}
// Attempt #1
void dataGridView1_CellStyleContentChanged(
object sender, DataGridViewCellStyleContentChangedEventArgs e)
{
// how to get cell itself (rowIndex & columnIndex)?
}
// Attempt #2
void dataGridView1_CellStyleChanged(object sender, DataGridViewCellEventArgs e)
{
// event only occurs when the Style property changes, but not Style.BackColor
}
// Attempt #3
void dataGridView1_CellFormatting(
object sender, DataGridViewCellFormattingEventArgs e)
{
// event rises so many times!
// and how to get reason of formatting (i need to detect only color change)?
}
// Attempt #4
// do i need something like this?
public class MyDataGridView : DataGridView
{
public class MyDataGridViewRowCollection : DataGridViewRowCollection
{
public MyDataGridViewRowCollection(DataGridView _dgv) : base(_dgv) { }
public class MyDataGridViewRow : DataGridViewRow
{
public class MyDataGridViewCellCollection : DataGridViewCellCollection
{
public MyDataGridViewCellCollection(DataGridViewRow _dgvRow) :
base(_dgvRow) { }
public class MyDataGridViewCell : DataGridViewCell
{
private new MyDataGridViewCellStyle Style { get; set; }
public class MyDataGridViewCellStyle : DataGridViewCellStyle
{
public new Color BackColor
{
get
{
return base.BackColor;
}
set
{
base.BackColor = value;
// TODO: changes in Excel
// ...
}
}
}
}
}
}
}
}
}
I will be glad to any advice and answers!
Discussion with #TaW prompted me to use several events at once.
We use CellStyleContentChanged event for detect Style.BackColor changes and CellFormatting event to get Cell, whose BackColor have been changed.
Also we need some Collection to store changed colors, because these events don't occur sequentially (see log below).
Remark!! This method only works for user-visible cells (DataGridView should not have scroll bars).
public partial class Form1 : Form
{
string log = "";
List<Color> changedBackColors = new List<Color>();
public Form1()
{
InitializeComponent();
this.dataGridView1.CellStyleContentChanged +=
dataGridView1_CellStyleContentChanged;
this.dataGridView1.CellFormatting +=
dataGridView1_CellFormatting;
this.Shown += Form1_Shown;
}
void Form1_Shown(object sender, EventArgs e)
{
log += "Change Cell[0,0] (color = blue)\r\n";
this.dataGridView1.Rows[0].Cells[0].Style.BackColor = Color.Blue;
log += "Change Cell[0,1] (color = red)\r\n";
this.dataGridView1.Rows[0].Cells[1].Style.BackColor = Color.Red;
}
private void Form1_Load(object sender, EventArgs e)
{
this.dataGridView1.Columns.Add("column1", "column1");
this.dataGridView1.Columns.Add("column1", "column1");
this.dataGridView1.Rows.Add("cell1", "cell2");
}
private void dataGridView1_CellStyleContentChanged(
object sender, DataGridViewCellStyleContentChangedEventArgs e)
{
log += string.Format(
"CellStyleContentChanged occurs for Cell[?,?] (color = {0})\r\n",
e.CellStyle.BackColor.Name);
this.changedBackColors.Add(e.CellStyle.BackColor);
}
private void dataGridView1_CellFormatting(
object sender, DataGridViewCellFormattingEventArgs e)
{
if (this.changedBackColors.Count > 0)
{
if (this.changedBackColors.Contains(e.CellStyle.BackColor))
{
log += string.Format(
"CellFormatting occurs for Cell[{0},{1}] (color = {2})\r\n",
e.RowIndex, e.ColumnIndex, e.CellStyle.BackColor.Name);
this.changedBackColors.Remove(e.CellStyle.BackColor);
// TODO: change excel file
// ...
}
}
}
}
Log:
Change Cell[0,0] (color = blue)
CellStyleContentChanged occurs for Cell[?,?] (color = Blue)
Change Cell[0,1] (color = red)
CellStyleContentChanged occurs for Cell[?,?] (color = Red)
CellFormatting occurs for Cell[0,0] (color = Blue)
CellFormatting occurs for Cell[0,1] (color = Red)
I am working on a graphing program and I want the user to customize their graph quickly and effectively. I have created a property grid which allows them to do that. I've populated it with the properties of a chart but removes certain elements I don't want the user to have access to. For instance I don't want the user to be able to have access to the accessibility options. So far what I have is
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
magRadioBox.Checked = true;
PropertyGrid propertyGrid1 = new PropertyGrid();
propertyGrid1.CommandsVisibleIfAvailable = true;
propertyGrid1.Text = "Graph and Plotting Options";
propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
this.Controls.Add(propertyGrid1);
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "MY Plot Program";
propertyGrid1.SelectedObject = chart1;
}
private void button1_Click(object sender, EventArgs e)
{//some code that is populating my chart(chart1) with data
.... //chart1 being filled with data
}
private void propertyGrid1_PropertyValueChanged(object s , PropertyValueChangedEventArgs e)
{
//Calling the method that will refresh my chart1
myChart.Invalidate();
}
The above code is for my Form. The my "MyChart" class code below sets up my property grid. I automatically get all of the properties of a chart and then can "cherry pick" the ones I don't want the user to have by setting it to [Browsable(false)]
namespace FFT_Plotter
{
[DefaultPropertyAttribute("Text")]
public class MyChart : Chart
{
public event EventHandler PropertyChanged;
private void OnPropertyChanged(object sender, EventArgs e)
{
EventHandler eh = propertyChanged;
if(eh !=null)
{
eh(sender, e);
}
[BrowsableAttribute(false)]
public new System.Drawing.Color BackColor
{
get { return BackColor; }//Here back color is just an example of a property, not necessarily one that I would make non-Browsable
set {
base.BackColor = value;
OnPropertyChanged(this,EventArgs.Empty);
}
}
}
}
The class above gets me so far as having a property grid that has all the properties of a chart and allows me to hide those properties as I see fit. However now I am stuck in understanding how to connect my chart1 to my property grid. An example would be I've removed the text property from the grid. It's no longer visible to the user. Now I want to be able to say change BackColor in the grid which means my chart1 back color changes.
Ok, I took your code and did the following and now changing the Background Color in the property grid changes the chart's background color:
Form1 -
public partial class Form1 : Form
{
private PropertyGrid propertyGrid1;
public Form1()
{
InitializeComponent();
//propertyGrid1 = new PropertyGrid();
propertyGrid1.CommandsVisibleIfAvailable = true;
propertyGrid1.Text = "Graph and Plotting Options";
propertyGrid1.PropertyValueChanged += propertyGrid1_PropertyValueChanged;
this.Controls.Add(propertyGrid1);
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "MY Plot Program";
propertyGrid1.SelectedObject = chart1;
}
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
{
//Calling the method that will refresh my chart1
chart1.Invalidate();
}
}
[DefaultPropertyAttribute("Text")]
public class MyChart : Chart
{
public event EventHandler PropertyChanged;
private void OnPropertyChanged(object sender, EventArgs e)
{
if(PropertyChanged !=null)
{
PropertyChanged(sender, e);
}
}
[BrowsableAttribute(false)]
public new string Text { get; set; }
[BrowsableAttribute(true)]
public new System.Drawing.Color BackColor
{
get { return base.BackColor; }//Here back color is just an example of a property, not necessarily one that I would make non-Browsable
set
{
base.BackColor = value;
OnPropertyChanged(this,EventArgs.Empty);
}
}
}
Also, in your Form1.Designer.cs file, you have chart1 defined as `System.Windows.Forms.DataVisualization.Charting.Chart you need to change that to be MyChart in the section where it is new'd (need to search for Charting.Chart)