Get back panel from clipboard - c#

This is my class, I always get a null insted of my panel...
Can someone give me a hint on how to do this?
[Serializable]
public class DragDropBlock : Panel
{
public DragDropBlock()
{
this.MouseDown += new MouseEventHandler(Mouse_Down);
this.MouseUp += new MouseEventHandler(Mouse_Up);
}
void Mouse_Down(object sender, System.Windows.Forms.MouseEventArgs e)
{
Clipboard.SetData("DragDropBlock", this);
}
void Mouse_Up(object sender, System.Windows.Forms.MouseEventArgs e)
{
IDataObject IBlock = Clipboard.GetDataObject();
DragDropBlock Block = (DragDropBlock)IBlock.GetData(typeof(DragDropBlock));
}
}

Given a class:
[Serializable]
class Test
{
public string Data
{
get;
set;
}
}
This works:
Test t = new Test()
{
Data = "DERP!"
};
Clipboard.SetData("Test", t);
Test newT = (Test)Clipboard.GetData("Test");
Console.WriteLine(newT.Data);
And if you want to use data objects:
Test t = new Test()
{
Data = "DERP!"
};
Clipboard.SetDataObject(new DataObject("Test", t));
Test newT = (Test)Clipboard.GetDataObject().GetData("Test");
Console.WriteLine(newT.Data);
The output to both of those is:
DERP!

This is the correction of my class: Working!!!
[Serializable]
class DragBlock
{
public string Data
{
get;
set;
}
}
public class DragDropBlock : Panel
{
DragBlock Block;
public DragDropBlock()
{
this.MouseDown += new MouseEventHandler(Mouse_Down);
this.MouseUp += new MouseEventHandler(Mouse_Up);
Block = new DragBlock()
{
Data = "TEST!"
};
}
void Mouse_Down(object sender, System.Windows.Forms.MouseEventArgs e)
{
Clipboard.SetDataObject(new DataObject("DragBlock", Block));
}
void Mouse_Up(object sender, System.Windows.Forms.MouseEventArgs e)
{
DragBlock newBlock = (DragBlock)Clipboard.GetDataObject().GetData("DragBlock");
Console.WriteLine(newBlock.Data);
}
}

Related

TextChanged event fires before bound text updates (Winforms .net6.0-winforms)

I want my price calculation to alter as I type, however the calculation is delayed.
My class is as follows
using System;
using System.Windows.Forms;
namespace MyClass
{
public class Model
{
public decimal Cost { get; set; }
public decimal MarkUp { get; set; }
public decimal Price { get; set; }
public decimal CalculatedPrice => Cost * (1 + MarkUp / 100);
}
public partial class FormTest : Form
{
public Model model { get; set; }
public FormTest()
{
InitializeComponent();
model = new Model
{
Price = 0,
MarkUp = 0
};
Calculate();
bs.Add(model);
textBoxCost.DataBindings.Add("Text", bs, "Cost", true, DataSourceUpdateMode.OnPropertyChanged);
textBoxMarkUp.DataBindings.Add("Text", bs, "MarkUp", true, DataSourceUpdateMode.OnPropertyChanged);
textBoxPrice.DataBindings.Add("Text", bs, "Price", true, DataSourceUpdateMode.OnPropertyChanged);
}
private void textBoxCost_TextChanged(object sender, EventArgs e)
{
Calculate();
}
private void Calculate()
{
model.Price = model.CalculatedPrice; // does not have the most up to date value
}
private void textBoxMarkUp_TextChanged(object sender, EventArgs e)
{
Calculate();
}
}
}
When I put a break in Calculate I see that the model has not updated.
What do I need to do?
[Update]
I now have the following:
public class Model : INotifyPropertyChanged
{
private decimal _cost;
public decimal Cost {
get => _cost;
set {
_cost = value;
var args = new PropertyChangedEventArgs(nameof(Cost));
PropertyChanged?.Invoke(this,args );
} }
private decimal _markup;
public decimal MarkUp {
get => _markup;
set {
_markup = value;
var args = new PropertyChangedEventArgs(nameof(MarkUp));
PropertyChanged?.Invoke(this, args);
} }
public decimal Price { get; set; }
public decimal CalculatedPrice => Cost * (1 + MarkUp / 100);
public event PropertyChangedEventHandler? PropertyChanged;
}
and
public partial class FormTest : Form
{
public Model model { get; set; }
public FormTest()
{
InitializeComponent();
}
private void Model_PropertyChanged(object? sender, PropertyChangedEventArgs e) { Calculate(); }
private void AddBinding(TextBox textBox, string dataMember)
{
var binding = new Binding(propertyName: "Text", dataSource: bs, dataMember:dataMember);
// binding.Format += Binding_Format; // yet to do
textBox.DataBindings.Add(binding);
}
private void Calculate() {
model.Price = model.CalculatedPrice;
}
private void FormTest_Load(object sender, EventArgs e)
{
model = new Model { Cost = 0, Price = 0, MarkUp = 0 };
model.PropertyChanged += Model_PropertyChanged;
bs.Add(model);
AddBinding(textBoxCost, "Cost");
AddBinding(textBoxMarkUp, "MarkUp");
AddBinding(textBoxPrice, "Price");
}
}
It works when I press Tab to exit a field.
How can I make it work when KeyUp occurs?
The TextChanged event has the same issue.
I tried issuing bs.EndEdit from within the event code but it did not help.
The following works
private void textBoxCost_KeyUp(object sender, KeyEventArgs e)
{
var tb = sender as TextBox;
model.Cost = Convert.ToDecimal( tb.Text);
Calculate();
}
private void textBoxMarkUp_KeyUp(object sender, KeyEventArgs e)
{
var tb = sender as TextBox;
model.MarkUp = Convert.ToDecimal(tb.Text);
Calculate();
}

Populating combobox using data from an API

The idea of this program is to retrieve the employee user ID (or signature) from an API URL once the name has been entered.
Right now my program shows no errors, however when I press start, my combo box (labeled "Name") doesn't show any suggestion as it is intended to. I would like it suggest name when the user is typing names (similar to how google works).
I have tried the ComboBox.DisplayMember, ComboBox.ValueMember, and ComboBox.DataSource, However, my data source is taken from an API JSON.
Thank you for your help in advance.
This is my JSON string:
[{
"signature": "JANDOW",
"firstName": "Jane",
"fullName": "Dow, Jane",
"lastName": "Dow"
}
]
My forms code is
namespace TimeSheets_Try_11
{
public partial class Form1 : Form
{
WebAPI WA = new WebAPI();
public Form1()
{
InitializeComponent();
webBrowser1.Url = new Uri(StaticStrings.UrlIora);
}
private void label1_Click(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
string sgname; string projectstring;
projectstring = comboBox1.Text.ToString();
sgname = WA.Getsignature(projectstring);
textBox2.Text = sgname;
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(AutoCompleteStringCollection combData)
{
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
}
}
}
Code for calling out the JSON is:
namespace TimeSheets_Try_11.Controllers
{
class WebAPI
{
public string Getsignature(string name)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var cookies = FullWebBrowserCookie.GetCookieInternal(new Uri(StaticStrings.UrlIora), false);
WebClient wc = new WebClient();
wc.Encoding = System.Text.Encoding.UTF8;
wc.Headers.Add("Cookie:" + cookies);
wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
wc.UseDefaultCredentials = true;
string uri = "";
uri = StaticStrings.UrlIora + name;
var response = wc.DownloadString(uri);
var status = JsonConvert.DeserializeObject<List<Employeename>>(response);
string signame = status.Select(js => js.signature).First();
return signame;
}
}
}
Code for defining variables is:
namespace TimeSheet_Try11_Models
{
public class Employeename
{
public string signature { get; set; }
public string firstName { get; set; }
public string fullName { get; set; }
public string lastName { get; set; }
}
public class Root
{
public List<Employeename> Employeename { get; set; }
}
}
Firstly, the JSON is an array. You need to change your method to accommodate for that:
public List<string> Getsignature(string name)
{
...
var status = JsonConvert.DeserializeObject<List<Employeename>>(response);
return status.Select(emp => emp.signature).ToList();
}
Then you need to bind up your ComboBox correctly:
private void button1_Click(object sender, EventArgs e)
{
comboBox1.DataSource = WA.Getsignature(textBox2.Text);
}

C# my Event is always Null... why...?

/* class library /
/ calcEventArgs.cs */
namespace calc1
{
public class calcEventArgs
{
}
public class CalculationCompletedEventArgs : System.EventArgs
{
public string StringValue { get; set; }
public int IntegerValue { get; set; }
}
}
/* CalcMain.xaml.cs */
namespace calc1
{
public partial class CalcMain : Page
{
public delegate void CalcEventHandler(object sender, CalculationCompletedEventArgs e);
public event CalcEventHandler CalculateCompletedEvent;
public CalcMain()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CalculationCompletedEventArgs pArgs = new CalculationCompletedEventArgs();
pArgs.StringValue = "1 + 1";
pArgs.IntegerValue = 2;
CalcEventHandler eh = CalculateCompletedEvent;
if (eh != null) eh(this, pArgs);
}
}
}
/* EventTest application program */
namespace EventTest
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
calc1.CalcMain c = new calc1.CalcMain();
c.CalculateCompletedEvent += new calc1.CalcMain.CalcEventHandler(CalcfromPage);
}
private void CalcfromPage(object sender, calc1.CalculationCompletedEventArgs e)
{
MessageBox.Show(e.StringValue + " = " + e.IntegerValue.ToString());
}
private void Button_Click(object sender, RoutedEventArgs e)
{
fraMainScreen.Navigate(new Uri("pack://application:,,,/calc1;component/CalcMain.xaml", UriKind.Absolute));
}
}
}
this is my code
i have problem ...
CalcEventHandler eh = CalculateCompletedEvent
CalculateCompletedEvent is always null..
help..
thanks. ^^

.net DispatcherTimer fires tick event repeatedly

i have problem in my code that i don't even near to understand.
Here is my item interface;
internal interface IItem
{
void Show();
event EventHandler Completed;
TimeSpan Duration { get; set; }
string Name { get; set; }
}
internal class ItemImage : IItem
{
public TimeSpan Duration { get; set; }
public string Name { get; set; }
public event EventHandler Completed;
private DispatcherTimer _dt = new DispatcherTimer();
public void Show()
{
_dt.Interval = this.Duration;
_dt.Tick += (s, e) =>
{
_dt.Stop();
Completed(this, new EventArgs());
};
_dt.Start();
}
}
And here's my player:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
int _pIndex = 0;
List<IItem> list = new List<IItem>();
private void Button1_Click(object sender, RoutedEventArgs e)
{
list = new List<IItem>()
{
new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image1" },
new ItemImage() { Duration = TimeSpan.FromSeconds(3), Name = "Image2" },
new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image3" },
new ItemImage() { Duration = TimeSpan.FromSeconds(7), Name = "Image4" }
};
Next();
}
void Next()
{
var tb = new TextBlock();
tb.Text = ((IItem)list[_pIndex]).Name;
StackPanel1.Children.Add(tb);
list[_pIndex].Completed += (s, e) =>
{
Next();
};
list[_pIndex].Show();
_pIndex++;
_pIndex %= list.Count;
}
}
First list plays with no problem but on second turn DispatcherTimer doesn't wait for my duration value, and immediately fires complete event. What do i do wrong?
Thanks.
I don't know exactly what is happening (I didn't test it), but I see that every time you call Show(), another eventhandler is attached to the Tick in your ItemImage object. This could lead to some side effects you'll experiencing.
You might change it to:
internal class ItemImage : IItem
{
public TimeSpan Duration { get; set; }
public string Name { get; set; }
public event EventHandler Completed;
private DispatcherTimer _dt = new DispatcherTimer();
// constructor
public ItemImage()
{
_dt.Tick += (s, e) =>
{
_dt.Stop();
Completed(this, new EventArgs());
};
}
public void Show()
{
_dt.Interval = this.Duration;
_dt.Start();
}
}
You could recreate the DispatcherTimer or move the event attaching to the constructor. (like above)
This is also done in the Next() method with list[_pIndex].Completed. (it attaches to a class member, so every buttonclick new handlers are added to the list.)
You might reconcider the style of attaching events. Like moving them to constructors.
Like:
public partial class MainWindow : Window
{
int _pIndex = 0;
List<IItem> list = new List<IItem>();
public MainWindow()
{
InitializeComponent();
list[_pIndex].Completed += (s, e) =>
{
_pIndex++;
_pIndex %= list.Count;
Next();
};
}
private void Button1_Click(object sender, RoutedEventArgs e)
{
list = new List<IItem>()
{
new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image1" },
new ItemImage() { Duration = TimeSpan.FromSeconds(3), Name = "Image2" },
new ItemImage() { Duration = TimeSpan.FromSeconds(5), Name = "Image3" },
new ItemImage() { Duration = TimeSpan.FromSeconds(7), Name = "Image4" }
};
Next();
}
void Next()
{
var tb = new TextBlock();
tb.Text = ((IItem)list[_pIndex]).Name;
StackPanel1.Children.Add(tb);
list[_pIndex].Show();
}
}
Good luck.

How to get all cell values form a Property Grid c#

I have a property Grid as follows:
I want to copy the complete content of the property grid to a data grid view(dataGeriView1) when submit button is clicked.
How to do this?
Please help.
private void Submit_Click(object sender, EventArgs e)
{
//propertyGrid1.SelectedObject = this;
dataGridView1.Columns.Add("Property", "Property");
dataGridView1.Columns.Add("Value", "Value");
GridItem gi = propertyGrid1.SelectedGridItem;
while (gi.Parent != null)
gi = gi.Parent;
foreach (GridItem item in gi.GridItems)
ParseGridItems(item); //recursive
dataGridView1.Sort(dataGridView1.Columns["Property"], ListSortDirection.Ascending);
}
private void ParseGridItems(GridItem gi)
{
if (gi.GridItemType == GridItemType.Category)
foreach (GridItem item in gi.GridItems)
ParseGridItems(item);
dataGridView1.Rows.Add(gi.Label, gi.Value);
}
Adapted from https://stackoverflow.com/a/12109186/1163434
Below is a sample snippet i have created to solve the above issue. Create a DataGridview by adding Columns Name,Age,Email,Phone.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Student std = new Student {Name = "Vimal" , Phone = "PhoneValue", Email="mymail",Age=24};
propertyGrid1.SelectedObject= std;
}
private void button1_Click(object sender, EventArgs e)
{
int index = dataGridView1.Rows.Count - 1;
Student std = (Student)propertyGrid1.SelectedObject;
dataGridView1.Rows[index].Cells["Name"].Value = std.Name;
dataGridView1.Rows[index].Cells["Age"].Value = std.Age;
dataGridView1.Rows[index].Cells["Email"].Value = std.Email;
dataGridView1.Rows[index].Cells["Phone"].Value = std.Phone;
}
}
public class Student
{
public int Age { get; set; }
public string Email { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
}

Categories