Silverlight Datagrid Refresh - silverlight

So I have a datagrid in Silverlight that is bound to a WCF that populates a list of class. I basically a pass a parameter to a Linq query. When I do a second query I get double the results, a third triple and so forth. What can I do to make it so when I send a call out to the service that I only get one set of results. I have attached my code in case it helps anyone.
private void button1_Click(object sender, RoutedEventArgs e)
{
dgOrder.ItemsSource = null;
Uri address = new Uri(Application.Current.Host.Source, "../Services/Service1.svc");
//var client = new Services.dataserviceClient("CustomBinding_dataservice", address.AbsoluteUri);
var client = new ServiceReference2.Service1Client("CustomBinding_Service1", address.AbsolutePath);
client.GetOrderCompleted += (s, ea) =>
{
dgOrder.AutoGenerateColumns = false;
//dgOrder.ColumnWidth.Value = 100;
dgOrder.Columns.Add(CreateTextColumn("SKU", "SKU"));
dgOrder.Columns.Add(CreateTextColumn("productname", "Product Name"));
dgOrder.Columns.Add(CreateTextColumn("itemnumber", "Item Number"));
dgOrder.Columns.Add(CreateTextColumn("cost", "Cost"));
dgOrder.Columns.Add(CreateTextColumn("asin", "ASIN"));
dgOrder.Columns.Add(CreateTextColumn("pendingorder", "Rank"));
dgOrder.Columns.Add(CreateTextColumn("rank", "Node"));
//dgOrder.Columns.Add(CreateTextColumn("w4", "AMZN"));
dgOrder.Columns.Add(CreateTextColumn("amazon", "AMZN"));
dgOrder.Columns.Add(CreateTextColumn("ourprice", "OurPrice"));
dgOrder.Columns.Add(CreateTextColumn("bbprice", "BuyBox"));
dgOrder.Columns.Add(CreateTextColumn("afner", "AFN"));
dgOrder.Columns.Add(CreateTextColumn("quantity", "INV"));
dgOrder.Columns.Add(CreateTextColumn("w4", "W4"));
dgOrder.Columns.Add(CreateTextColumn("w3", "W3"));
dgOrder.Columns.Add(CreateTextColumn("w2", "W2"));
dgOrder.Columns.Add(CreateTextColumn("w1", "W1"));
dgOrder.Columns.Add(CreateTextColumn("order", "Order"));
dgOrder.Columns.Add(CreateTextColumn("total", "Total"));
dgOrder.Columns.Add(CreateTextColumn("profit", "Profit"));
dgOrder.Columns.Add(CreateTextColumn("percent", "Percent"));
dgOrder.Columns.Add(CreateHyperlink("asin"));
dgOrder.ItemsSource = ea.Result;
Original = ea.Result;
};
client.GetOrderAsync(txtCompany.Text);
}

The problem is , you are creating a new(duplicate) event handler every time you press the Button. Due to having an extra event for each button pres you do, you get extra sets of data. You need to create your Event.Completed method outside the Button.Cliked event.
To clarify:
public partial class NewPage : Page
{
Uri address = new Uri(Application.Current.Host.Source, "../Services/Service1.svc");
ServiceReference2.Service1Client client = new ServiceReference2.Service1Client("CustomBinding_Service1", address.AbsolutePath);
public NewPage()
{
client.GetOrderCompleted += (s, ea) =>
{
//YOUR CODE
};
}
private void button1_Click(object sender, RoutedEventArgs e)
{
dgOrder.ItemsSource = null;
client.GetOrderAsync(txtCompany.Text);
}
}

Related

Dapper Bulk Delete how to report progress

I am using Dapper Plus to do a bulk insert using a query from another table my question is here how does one report progress. As you see I am using the background worker process to run my code which works fine however as the bulk delete method does not have a reportprogress event how would I handle this.
public StockDeativationForm()
{
InitializeComponent();
this._backgroundWorker.DoWork += new DoWorkEventHandler(this.BackgroundWorkerDoWork);
this._backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(this.BackgroundWorkerProgressChanged);
this._backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BackgroundWorkerRunWorkerCompleted);
}
private void BackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
{
ProcessStockItems();
}
private void BackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.progressBar2.Value = e.ProgressPercentage;
}
private void BackgroundWorkerRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
this.CompleteProcess();
}
private void CompleteProcess()
{
MessageBox.Show("Stock items Deleted", "Stock Item Delete", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
base.Close();
}
public StockDeativationForm()
{
InitializeComponent();
this._backgroundWorker.DoWork += new DoWorkEventHandler(this.BackgroundWorkerDoWork);
this._backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(this.BackgroundWorkerProgressChanged);
this._backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(this.BackgroundWorkerRunWorkerCompleted);
}
private void ProcessStockItems()
{
string conStr = ConfigurationManager.AppSettings["DeleteStock"];
using (var connection = new SqlConnection(conStr))
{
DialogResult _dialogResult = MessageBox.Show(null, "Are you sure you want to delete stock? This will delete all stock items", "Delete Stock", MessageBoxButtons.YesNo);
if (_dialogResult == DialogResult.Yes)
{
connection.BulkDelete(connection.Query<StockItems>("Select ItemID FROM StockItem").ToList());
}
}
}
How does one report progress back using this method of bulkdelete
connection.BulkDelete(connection.Query<StockItems>("Select ItemID FROM StockItem").ToList());
Disclaimer: I'm the owner of Dapper Plus
You are right,
Perhaps using the log event could work?
StringBuilder log = new StringBuilder();
connection.UseBulkOptions(options => options.Log = s => {
if(s.Contains("...xyz...")) {
log.AppendLine(s);
}
}).BulkDelete(connection.Query<StockItems>("Select ItemID FROM StockItem").ToList());
Another solution will be to report this request to our support team and ask for a Report Progress/Notify event.

Prevent RepositoryItemSearchLookUpEdit when Popup is Open When CloseUpKey.Key is pressed

I use a RepositoryItemSearchLookUpEdit. its CloseUpKey property is set to space
result.CloseUpKey = new DevExpress.Utils.KeyShortcut(System.Windows.Forms.Keys.Space);
I want to use this shortcut only for open popup and not for closing popup.
How can I achieve this?
UPDATE------------------------
First I create an RepositoryItemSearchLookUpEdit object
var result = new RepositoryItemSearchLookUpEdit();
result.CloseUpKey = new DevExpress.Utils.KeyShortcut(System.Windows.Forms.Keys.Space);
result.KeyDown += repositoryItemLookUpEdit_KeyDown;
result.CloseUp += repositoryItemLookUpEdit_CloseUp;
result.QueryCloseUp += repositoryItemLookUpEdit_QueryCloseUp;
private void repositoryItemLookUpEdit_QueryCloseUp(object sender, System.ComponentModel.CancelEventArgs e)
{
var edit = sender as SearchLookUpEdit;
KeyEventArgs k = new KeyEventArgs(edit.Properties.CloseUpKey.Key);
AttachKeyPressEvent(k);
if (k.KeyCode == edit.Properties.CloseUpKey.Key)
e.Cancel = true;
}
And pass it to a grid column:
grdListView.Columns["yyy"].ColumnEdit = result
How can I achieve that with these events, without creating a descendant SearchLookUpEdit
UPDATED:
The problem is that CloseUp event (where you could get the necessary info about the closeup key) occurs after the QueryCloseUp event (where you could precent the closing up event). Also the KeyPress, KeyDown and KeyUp events seem also NOT to occur when the QueryCloseUp occurs, as a result they couldn't be overridden. So I tried this, I created a custom KeyEventHandler and triggered him during QueryCloseUp event in order to get the necessary info of what key was pressed and cancel the event if the close key event was the one. Here is my codeTry it to see if it suits you
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//Here you can add your grid control as you have created
DataTable dt = new DataTable();
dt.Columns.Add("ID"); //use your own names and types
gridControl1.DataSource = dt;
var result = new RepositoryItemSearchLookUpEdit();
result.CloseUpKey = new DevExpress.Utils.KeyShortcut(System.Windows.Forms.Keys.Space);
result.QueryCloseUp += new CancelEventHandler(repositoryItemLookUpEdit_QueryCloseUp);
((gridControl1.MainView as GridView).Columns["ID"] as GridColumn).ColumnEdit = result;
}
private static readonly object myQueryCloseUp = new object();
public event KeyEventHandler MyQueryCloseUp
{
add { Events.AddHandler(myQueryCloseUp, value); }
remove { Events.RemoveHandler(myQueryCloseUp, value); }
}
protected virtual void AttachKeyPressEvent(KeyEventArgs e)
{
KeyEventHandler handler = (KeyEventHandler)Events[myQueryCloseUp];
if (handler != null)
handler(this, e);
}
//Here you add your own Handler implementation
public void repositoryItemLookUpEdit_QueryCloseUp(object sender, CancelEventArgs e)
{
KeyEventArgs k = new KeyEventArgs((sender as SearchLookUpEdit).Properties.CloseUpKey.Key);
AttachKeyPressEvent(k);
if (k.KeyCode == (sender as SearchLookUpEdit).Properties.CloseUpKey.Key)
e.Cancel = true;
}
}

WPF - Canvas won't update when BackgroundWorker is completed

I need to update my Canvas when BackgroundWorker is completed. When i update the Canvas through a button actionlistener it works perfect. But when i call my update function when backroundWorker is completed. The gui won't update.
The function that add items to the canvas:
public void AddItemsToCanvas()
{
int factor = 0;
cvList.Children.Clear();
foreach (ItemControl item in ItemControl.ItemsList)
{
cvList.Children.Add(item.updateName);
Canvas.SetLeft(item.updateName, 13);
Canvas.SetTop(item.updateName, factor + 10);
Canvas.SetZIndex(item.updateName, 1);
cvList.Children.Add(item.imageButton);
Canvas.SetLeft(item.imageButton, 180);
Canvas.SetTop(item.imageButton, factor + 13);
Canvas.SetZIndex(item.imageButton, 5);}}
The button that calls the update function:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
updateCanvas();
}
public void updateCanvas()
{
Service serv = new Service();
serv.SuperlinkCompartments();
//Check for updates and add them to a List of updates
Update up = new Update();
up.PropertyChanged += new PropertyChangedEventHandler(Items_PropertyChanged);
up.ShowUpdates();
}
public void Items_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
AddItemsToCanvas();
}
The Canvas updates perfectly when called from the button actionListener. But not working when the UpdateCanvas() is called from the BackgroundWorker event.
public void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
var item = dic3[(BackgroundWorker)sender];
int index = (int)item.controlButton.Tag;
item.Progressbar.Value = 0;
SystemInfo.SystemList[Update.UpdateList[index].SystemIndex].Version = Update.UpdateList[index].UpdateVersion;
lvSystems.ItemsSource = SystemInfo.SystemList;
updateCanvas();
}
I'm i missing something in the BackgroundWorker event function?
try using the `Dispatcher':
Application.Current.Dispatcher.Invoke(new Action(()=>
{
updateCanvas();
}), DispatcherPriority.Render);
then, inside your updateCanvas() method, add the following at the end:
cvList.UpdateLayout();

Silverlight InvalidOperationException when clicking a link

I have a dynamically generated hyperlink which when clicked should open a lotus notes document. I do it using the code below.
HyperlinkButton hlb = new HyperlinkButton();
hlb.SetBinding(HyperlinkButton.ContentProperty, new Binding("Properties[" + col.DisplayField + "]"));
hlb.SetBinding(HyperlinkButton.NavigateUriProperty, new Binding("Properties[" + col.LinkField + "]"));
hlb.Click += new RoutedEventHandler(hlb_Click);
RootGrid.Children.Add(hlb);
this is the code that fires when the link is clicked.
static void hlb_Click(object sender, RoutedEventArgs e)
{
HyperlinkButton hlb = (HyperlinkButton)sender;
var hostingWindow = HtmlPage.Window;
hostingWindow.Navigate(hlb.NavigateUri);
}
the lotus notes document opens correctly but I get a System.InvalidOperationException, the details of which are given below
Description: Failed to navigate to notes://<path to the document>
Stacktrace:
at MS.Internal.NavigationHelper.Navigate(Boolean checkUserInitiatedAction)
at System.Windows.Controls.HyperlinkButton.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.Controls.Control.OnMouseLeftButtonUp(Control ctrl, EventArgs e)
at MS.Internal.JoltHelper.FireEvent(IntPtr unmanagedObj, IntPtr unmanagedObjArgs, Int32 argsTypeIndex, Int32 actualArgsTypeIndex, String eventName)
Another interesting thing to note is that it is raised on another thread and hence is not caught when the hostingWindow.Navigate method is fired.
Any ideas ?
Using Silverlight 5, I wrapped the call to open the Lotus Notes doc link within a task and was able to open the link without generating an error.
private void TryOpenDocLink()
{
TaskScheduler ts = TaskScheduler.Default;
Task<bool> task = OpenDocLink();
task.ContinueWith(t =>
{
if (t.Exception != null)
{
this.SetError(t.Exception.Message, enMessageLevel.Error);
}
});
}
private Task<bool> OpenDocLink()
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
try
{
var hostWindow = HtmlPage.Window;
hostWindow.Navigate(new Uri(DocLinkPath));
tcs.SetResult(true);
}
catch (Exception)
{
tcs.SetResult(false);
}
return tcs.Task;
}
Try marking the click event as handled:
static void hlb_Click(object sender, RoutedEventArgs e)
{
e.Handled = true;
HyperlinkButton hlb = (HyperlinkButton)sender;
var hostingWindow = HtmlPage.Window;
hostingWindow.Navigate(hlb.NavigateUri);
}
I'm not sure that this will fix the issue. The error is coming from the click event code inside the hyperlink button. You can tell because that code uses the NavigationHelper class while the Window.Navigate method does not.
Is there a reason you're not just letting the hyperlink button do the navigation?

WPF WebBrowser: How to set element click event?

I've figured out how to make everything red as soon as the page is finished loading:
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
var doc = (IHTMLDocument2)webBrowser1.Document;
foreach (IHTMLElement elem in doc.all)
{
elem.style.backgroundColor = "#ff0000";
}
}
Now what if I want to make the element only change color when it's clicked? I see that elem has an onclick property, but it's type is dynamic so I don't know what to do with it. The documentation is pretty useless.
You could do it by using the HTMLDocumentClass instead of the IHTMLDocument2 interface:
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
doc.HTMLDocumentEvents_Event_onclick += new mshtml.HTMLDocumentEvents_onclickEventHandler(OnClickHandler);
}
bool OnClickHandler()
{
mshtml.HTMLDocumentClass doc = (mshtml.HTMLDocumentClass)webBrowser1.Document;
mshtml.IHTMLWindow2 win = doc.parentWindow;
win.#event.srcElement.style.backgroundColor = "#ff0000";
return false;
}
}
The above solution, has one drawback: the onclick event does not bubble, even though false is returned (i.e. clicking at hyperlinks does not navigate to other pages).

Resources