pass a variable to the result of an asynchronous call method's - wcf

There is a DataGrid with data in the Net 4.0 App. For the selected row, I get the value of one of the columns and pass it to the asynchronous method of the WCF service. Is it possible to pass this value as a result this method?
btn_Click(object sender, RoutedEventArgs e) {
DataRowView rv = (DataRowView)dgData.SelectedItem;
rv["TimeBeg"] = DateTime.Now.ToString("h:mm:ss");
string val=rv["Id"].ToString();
srAsync.ServClient clP = new srAsync.ServClient();
clP.MethodCompleted += cl_MethodComplete;
clP.MethodAsync(val);
}
After the call, the user can select another DataGrid Item, and call Async method for them, but in complete method I need to call another method with this value and update the rows DataGrid
private void cl_MethodComplete(object sender, srA.MethodCompletedEventArgs e) {
rv["TimeEnd"] = DateTime.Now.ToString("h:mm:ss");
sr.ServClient clP = new sr.ServClient();
clP.AnotherMethod(val);
...

What I would do is passing the row the user clicks on to the handler, using a lambda function:
btn_Click(object sender, RoutedEventArgs e) {
DataRowView rv = (DataRowView)dgData.SelectedItem;
rv["TimeBeg"] = DateTime.Now.ToString("h:mm:ss");
string val = rv["Id"].ToString();
srAsync.ServClient clP = new srAsync.ServClient();
clP.MethodCompleted += (currentSender, currentE) => cl_MethodComplete(currentSender, currentE, rv);
clP.MethodAsync(val);
}
Of course you will have to add another parameter to cl_MethodComplete, which will be able to work on the original row:
private void cl_MethodComplete(object sender, srA.MethodCompletedEventArgs e, DataRowView originalRow) {
originalRow["TimeEnd"] = DateTime.Now.ToString("h:mm:ss");
sr.ServClient clP = new sr.ServClient();
clP.AnotherMethod(val);
...

Related

Load dropdown with Database Data

I'm new in windows forms and I have comboBox called cbTasks and I want to populate it in load window so I execute sql task as:
private void StatusForm_Load(object sender, EventArgs e)
{
var db = new SQLConnMgr();
var taskType = string.Format("SELECT [Name], [Id] FROM [TaskType] WHERE TaskTypeCategoryId = {0} ", TaskTypeCategoryId);
var taskList = db.GetTableBySQL(taskType);
}
As you can see I have items into taskList variable, but now I want to fill comboBox. How can I achieve that? I try to use foreach but I don't know how to call [Name] into Add method:
foreach(DataRow task in taskList.Rows)
{
cbTasks.Items.Add()
}
How can I achieve that? Regards
Just bind tghe datatable to the dropdown, the dot new framework does the looping for you behind the scenes:
cbTasks.DataSource = taskList;
cbTasks.DisplayMember = "Name";
cbTasks.ValueMember = "Id";

datagridview ,CurrentCellChanged,AllowUserToAddRows,textbox.keydown event

my question is why add a textbox controls to datagridview ,then press keyboard to add a blank row to datagridview . but i find the cursor always jump to above row's cell,not position where i press keyboard's cell.so i get confused .
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Visible = false;
textBox1.Width = 0;
dataGridView1.Controls.Add(textBoxenter code here1);
System.Data.DataTable dt = new DataTable();
dt.Columns.Add("Name");`enter code here`
dt.Columns.Add("Sex");
System.Data.DataRow dr;
for (int i = 0; i < 10; i++)
{
dr = dt.NewRow();
dr["Name"] = string.Format("Name{0}", i);
dr["Sex"] = string.Format("Sex{0}", i);
dt.Rows.Add(dr);
}
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = dt;
}
private void dataGridView1_CurrentCellChanged(object sender, EventArgs e)
{
this.textBox1.Visible = false;
this.textBox1.Width = 0;
try
{
if (dataGridView1.Columns[dataGridView1.CurrentCell.ColumnIndex].HeaderText == "Name")
{
this.textBox1.Left = dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, true).Left;`</i>`
this.textBox1.Top = dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, true).Top;`</i>`
this.textBox1.Width = dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, true).Width - 2;`</i>enter code here`
this.textBox1.Height = `</i>`dataGridView1.GetCellDisplayRectangle(dataGridView1.CurrentCell.ColumnIndex, dataGridView1.CurrentCell.RowIndex, true).Height - 2;
`</i>`
string str = Convert.ToString(this.dataGridView1.CurrentCell.Value); this.textBox1.Text = str;
this.textBox1.Visible = true;
}
}
catch
{
}
}
private void textBox1_Validating(object sender, CancelEventArgs e)
{
this.dataGridView1.CurrentCell.Value = this.textBox1.Text;
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1 .AllowUserToAddRows =true ;
}
}
}
Alright, against my better judgement I will provide an partial answer for this.
First off, this is not VB.NET, this is C#.
Secondly, I can't find any code that actually adds a row for you or indicates that you have tried it. So I will only answer the problem you state in your comment. This since it seems a bit to hard for you to grasp and I want to be helpful.
Which is: "The question is why i press a key in textbox, the cell position would be move to the above cell".
This happens when you have selected the new row with an asterix ( * ) as row number. This is called a "Manually added row".
So now when you try to add text from your textbox you select the last row and start typing in the textbox. What happends then is that the event KeyDown is fired and it executes this command:
this.dataGridView1.AllowUserToAddRows = false;
Which, to make things simple, means "Delete the row with the asterix ( * )". So now the last row no longer exist and the DataGridView needs a new selection. The selection is then passed to the row above. So now the second last row is the last row, and it will be selected. Then you execute this command:
this.dataGridView1 .AllowUserToAddRows =true;
Which means "Create the row with the asterix ( * )", thus making the last row appear again. However, the second last row selection is not affected by adding this row again. So it remains selected. This creates the endresult that the selection jumps up to the line above.

RoutedEventArgs and AllFramesEventArgs

I am trying to call a function whose parameters are object sender and RoutedEventsArg e. I need those parameters since I have created a button on the main window related to this function and when I click the button it links to my function.
protected void StartRecord(object sender,RoutedEventsArg e)
{
// some stuff that creates a button and then does stuff
}
In another function, I need to call the above function stated above, but this second function has a parameter of AllFramesReadyArg e, not RoutedEventsArg e. So how do i call out the first function
void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
this.StartRecord(sender, e);
// does not work since parameter calls for RoutedEventArgs
}
Your StartRecord is not part of the Kinect Toolbox. You appear to have written it and given it those two arguments. It doesn't need them, nor do you necessarily need the function.
You also do not want to be calling StartRecord in AllFramesReady. The AllFramesReady callback is fired every time all the frames are ready for processing (hence the function name), which happens roughly 30 times a second. You only need to tell it to record once.
Per your other question, StartRecord is a callback to a button -- it shouldn't be called in code. It is called when the user hits the associated button.
Just looking at the Kinect Toolbox code and the callbacks, your code should look something like this:
KinectRecorder _recorder;
File _outStream;
bool _isRecording = false;
private void KinectSetup()
{
// set up the Kinect here
_recorder = new KinectRecorder(KinectRecordOptions.Skeleton, _outStream);
// some other stuff to setup
}
private void sensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
SkeletonFrame skeleton;
if (_isRecording && skeleton != null)
{
_recorder.Record(skeleton);
}
}
public void StartRecord(object sender, RoutedEventsArg e)
{
_isRecording = !_isRecording;
}

Calling a async method multiple times with different parameter Silverlight 4.0

I am calling a async method having a single parameter, It will return me the result according to parameter. I am calling that method more than one time with different parameter value, but in Completed event i am getting the same value for all.
client.ListAllLookupValuesByTypeCompleted += client_ListAllAddressFormatCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat");
client.ListAllLookupValuesByTypeCompleted += client_ListAllPhoneFormatCompleted;
client.ListAllLookupValuesByTypeAsync("PhoneFormat");
void client_ListAllAddressFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbAddressFormat.ItemsSource = e.Result;
}
void client_ListAllPhoneFormatCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
cmbPhonePrintFormat.ItemsSource = e.Result;
}
But getting same value in e.Result.
any suggetions. Thanks.
Your method may return a different value based on the first parameter, but both handlers will be called at the same time every time, regardless of what you send it. If this is a standard webservice reference, then you should see an object userState parameter available for you and this can be used to determine what to do.
client.ListAllLookupValuesByTypeCompleted += client_ListAllLookupValuesCompleted;
client.ListAllLookupValuesByTypeAsync("AddressFormat", true);
client.ListAllLookupValuesByTypeAsync("PhoneFormat", false);
void client_ListAllLookupValuesCompleted(object sender, ListAllLookupValuesByTypeCompletedEventArgs e)
{
// e.UserState will either be false or true
if ((bool)e.UserState)
cmbAddressFormat.ItemsSource = e.Result;
else
cmbPhonePrintFormat.ItemsSource = e.Result;
}

"Object reference not set to an instance of an object" While Adding to a List

I need some help with my program. I get this error when I run my VB.NET program with a custom DayView control.
************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at SeaCow.Main.DayView1_ResolveAppointments(Object sender, ResolveAppointmentsEventArgs args) in C:\Users\Daniel\My Programs\Visual Basic\SeaCow\SeaCow\SeaCow\Main.vb:line 120
at Calendar.DayView.OnResolveAppointments(ResolveAppointmentsEventArgs args)
at Calendar.DayView.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
According to the error code, the 'for each' loop below is causing the NullReferenceException error. At default, the 'appointments' list is assigned to nothing and I can't find where the ResolveAppointments function is being called at.
Private Sub DayView1_ResolveAppointments(ByVal sender As Object, ByVal args As Calendar.ResolveAppointmentsEventArgs) Handles DayView1.ResolveAppointments
Dim m_Apps As New List(Of Calendar.Appointment)
For Each m_App As Calendar.Appointment In appointments
If (m_App.StartDate >= args.StartDate) AndAlso (m_App.StartDate <= args.EndDate) Then
m_Apps.Add(m_App)
End If
Next
args.Appointments = m_Apps
End Sub
Here is the OnResolveAppointments and ResolveAppointment functions from the DayView.cs control file.
public event EventHandler<ResolveAppointmentsEventArgs> OnResolveAppointments;
protected virtual void ResolveAppointments(ResolveAppointmentsEventArgs args)
{
System.Diagnostics.Debug.WriteLine("Resolve app");
if (OnResolveAppointments != null)
OnResolveAppointments(this, args);
this.allDayEventsHeaderHeight = 0;
// cache resolved appointments in hashtable by days.
cachedAppointments.Clear();
if ((selectedAppointmentIsNew) && (selectedAppointment != null))
{
if ((selectedAppointment.StartDate > args.StartDate) && (selectedAppointment.StartDate < args.EndDate))
{
args.Appointments.Add(selectedAppointment);
}
}
foreach (Appointment appointment in args.Appointments)
{
int key = -1;
AppointmentList list;
if (appointment.StartDate.Day == appointment.EndDate.Day && appointment.AllDayEvent == false)
{
key = appointment.StartDate.Day;
}
else
{
key = -1;
}
list = (AppointmentList)cachedAppointments[key];
if (list == null)
{
list = new AppointmentList();
cachedAppointments[key] = list;
}
list.Add(appointment);
}
}
Also, here is the OnPaint method
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// resolve appointments on visible date range.
ResolveAppointmentsEventArgs args = new ResolveAppointmentsEventArgs(this.StartDate, this.StartDate.AddDays(daysToShow));
ResolveAppointments(args);
using (SolidBrush backBrush = new SolidBrush(renderer.BackColor))
e.Graphics.FillRectangle(backBrush, this.ClientRectangle);
// Visible Rectangle
Rectangle rectangle = new Rectangle(0, 0, this.Width - VScrollBarWith, this.Height);
DrawDays(ref e, rectangle);
DrawHourLabels(ref e, rectangle);
DrawDayHeaders(ref e, rectangle);
}
Anyone have any suggestions?
DayView1_ResolveAppointments is clearly an event handler for the ResolveAppointments event of the DayView1 control. If the For Each is throwing the exception, then it means that appointments is Nothing at that time, and not an empty list, as you expect it to be. Add
If appointments Is Nothing Then
Return
End If
before the For Each loop.
It appears that your Calendar.DayView control calls the OnResolveAppointments function within its override of OnPaint. I would suggest you examine the code there.
In the meantime, you could probably just skip over the For Each if appointments is Nothing.