DataTable validation: ColumnChanging vs RowChanging - validation

Here is my form code which saves dataset:
salesInvoiceBindingSource.EndEdit();
salesInvoiceLineBindingSource.EndEdit();
if (invoiceDataSet.HasChanges() && !invoiceDataSet.HasErrors)
{
this.tableAdapterManager.UpdateAll(this.invoiceDataSet);
}
I've noticed that if I put validation code in ColumnChanging event:
void SalesInvoiceDataTable_ColumnChanging(object sender,
System.Data.DataColumnChangeEventArgs e)
{
if (e.Column.ColumnName == "CustomerCode")
{
if (string.IsNullOrWhiteSpace((string)e.ProposedValue))
e.Row.SetColumnError("CustomerCode", "Required");
else
e.Row.SetColumnError("CustomerCode", string.Empty);
}
}
}
then invoiceDataSet.HasErrors is false even when CustomerCode is empty string, because the event fires after dataset is saved. But if I put validation code in RowChanging event, it fires before UpdateAll() method; so it works fine. Why is it that? I'd like to use ColumnChanging event, not RowChanging event.
EDIT: This happens to new records, which were created by:
salesInvoiceBindingSource.AddNew();

Most operations that add or delete rows do not raise the ColumnChanged and ColumnChanging events

Related

Devexpress GridControl : Prevent new row added automatically

Please guide me how to prevent new rows added automatically on DevExpress.XtraGrid.GridControl
I want to control when new rows is added, in my case i'm using a keydown event (CTRL + I ) for this task. But the grid keep adding new rows automatically if i move the focus (cursor pointer) to the area right below to the last row and click.
The GridControl.MainView is a BandedGridView, which contains the datasource.
You can use BandedGridView.OptionsView.NewItemRowPosition property. You can set its value to NewItemRowPosition.None to hide new item row.
Another way is to handle BandedGridView.ShownEditor event. Inside of this you can check if BandedGridView.FocusedRowHandle property is equals to GridControl.NewItemRowHandle and cancel editor activation.
Here is example:
private void bandedGridView1_ShowingEditor(object sender, CancelEventArgs e)
{
if (bandedGridView1.FocusedRowHandle == GridControl.NewItemRowHandle)
{
// Do here additional checks if you need. After your checks set e.Cancel to true.
e.Cancel = true;
}
}
You can handle the ValidateRow event. If you set e.Valid = false you wont add a new row. So check if your object is empty or invalid and just if the needed values are typed you give the row free.
private void grvMyView_ValidateRow(object sender, ValidateRowEventArgs e)
{
if (grvMyView.IsNewItemRow(e.RowHandle))
{
MyObject obj = grvMyView.GetRow(e.RowHandle) as MyObject;
e.Valid = obj.IsValid();
}
}
As of version 15 you can simply set your TableView's NewItemRowPosition to NewItemRowPosition.None. Be sure to call CommitEditing() on your TableView first.

GWT capture event in RichTextArea or in IFrame

I have a RichTextArea
private RichTextArea richTextArea;
and I'm trying to capture a paste event like this:
DOM.sinkEvents((com.google.gwt.user.client.Element) richTextArea.getElement(), com.google.gwt.user.client.Event.ONPASTE);
DOM.setEventListener((com.google.gwt.user.client.Element) richTextArea.getElement(), new EventListener(){
#Override public void onBrowserEvent(Event event) {
switch (event.getTypeInt()) {
case Event.ONPASTE: Window.alert("hey");break;
}
}
});
But it doesn't work, when I paste text on the richTextArea the alert is not triggered.
Any idea how to capture this paste event?
Thanks!
You cannot add the event to the RichTextArea, which actually is an iframe, but to it's body.
Although you could use jsni, I would use gwtquery because its simplicity:
// First attach the widget to the DOM
RootPanel.get().add(richTextArea);
// We only can bind events to the content, once the iframe document has been created,
// and this happens after it has been attached. Note that richtTextArea uses a timeout
// to initialize, so we have to delay the event binding as well
$(richTextArea).delay(1, lazy().contents().find("body").bind(Event.ONPASTE, new Function(){
#Override public boolean f(Event e) {
Window.alert("OnPaste");
return true;
}
}).done());
Have you seen the rendered HTML of RichTextArea ? it's an iframe not an actual textarea input type. it sets the user input under a body element. So that's why you don't get sinked onpaste events. For example if you listen to onpaste on TextArea widget it works fine.
private static class MyTextArea extends TextArea
{
public MyTextArea()
{
sinkEvents(Event.ONPASTE);
}
#Override
public void onBrowserEvent(Event event)
{
if(event.getTypeInt() == Event.ONPASTE)
{
Window.alert("text pasted !");
}
super.onBrowserEvent(event);
}
}
maybe you can bind a handler to that iframe body element using JSNI and get the callback on that event (haven't tried it though )
Just for the sake of completeness, the native (JSNI) solution would be something like:
setPastehandler(richTextArea.getElement());
private native void setPasteHandler(Element e) /*-{
e.contentDocument.onpaste = function (event) {
alert("pasted!");
};
}-*/;

ExtJS menu checkItem: how to prevent item check event in certain circumstance?

for a menu checkItem, when user clicks at it, by default it will trigger checkchange; i am wondering how to, if a certain case is met, not change its check status after clicked, in other words, stop this event chain.
I tried following codes, but not work:
listeners: {
'click': function(item, evt) {
if(1) { //verify whether that certain case
evt.stopEvent(); //since click_event is triggered before setChecked()/checkChange, I thought this may stop its going further...
alert('case met!');
}
},
checkHandler: function(item, checked) {
//...
}
You can listen to the beforecheckchange event. Here it is in the docs.
As per the docs, just apply your conditional logic and if it doesn't pass, return false from the handler.
E.g.:
listeners: {
'beforecheckchange': function(item, checked) {
if(!1) { // or whatever your conditional logic is
return false;
}
},
}

Listpicker: fire SelectionChanged

I am setting selecteditem manually
public pageXXXX()
{
InitializeComponent();
this.cargaLista();
}
private void cargaLista()
{
this.lPickTipo.SelectedItem = this.lPickTipo.Items.OfType<tipos>().First(i => i.tipo == varString);
// here i load other data
//
}
Ok. Runs fine.
But my problem is that selectionchanged event is fire last, not when I set manually the SelectedItem
This is a problem for me. Because I run calc inside "SelectionChanged" event and I need to run calc when I selecteditem because other functions depend on this result
private void lPickTipo_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
if (this.lPickTipo.SelectedItem != null)
{
if (lPickTipo.SelectedIndex > -1)
{
this.calcularTotales();
}
}
}
catch (Exception EXC)
{ // CACTHING }
}
Why is fire last? How I can solve this?
In that you can't change the order that system level events are raised you'll need to change your logic to account for what the platform does.
As you haven't provided any information on what you're actually basing on the selection or why it requires page (presumably) level events to be fired after the selection is changed it's hard to be more specific.

Can't tombstone ItemsSource of a ListBox

I have a ListBox populated with data coming from XML.
Fine so far, the problem is that I get some errors when I try to tombstone it.
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
State["listbox1"] = listBox1.ItemsSource;
}
Then:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
if (State.ContainsKey("listbox1"))
{
listBox1.ItemsSource = (IEnumerable)State["listbox1"];
}
}
When I hit the start button I already get an error. The App.xaml.cs opens and the line below becomes yellow
System.Diagnostics.Debugger.Break();
I've also used tombstoning helper but it did not return the items in my listbox.
What is the listbox bound to? And what error are you seeing?
If it's a DataServiceCollection, you may have tracking turned on & you cannot put it flatly in Isolated Storage or State dictionaries. Should be fine if using ObservableCollection.
Thanks!

Resources