Skip to main content

Microsoft Silverlight

Answered Question Abort binding in ConvertBack method & Getting DataContextRSS Feed

(0)

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Abort binding in ConvertBack method & Getting DataContext

Hi,

I have two questions: 

Question 1:
I would like to abort a binding if an incorrect value is received in the ConvertBack method of an IValueConverter class. Here is the simple example code:

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
try
{
// If the received value is a float, bind it..
float f = float.Parse(value.ToString());
return f;
}
catch
{
HtmlPage.Window.Alert("The received value is not a float.");

// ***** SOMETHING HERE TO ABORT BINDING AND REVERT TO THE PREVIOUS VALUE OF THE TEXTBOX, IF ANY *****

}
}

 

Question 2:
I would also like to get the datacontext of the object that activated the ConvertBack method, to be able to update other parts of the DataContext if an acceptable value was received. For example, a Person object gets a Salary value passed to the ConvertBack, but if it is a valid salary, I would also like to update the SalaryDate for the Person.

I have previously done this by catching the sender as a Textbox (before I used Converters) and simply getting a new instance of Person and setting it to the Textbox.DataContext value. Easy. But now I'm unsure how to do that with a Converter.

 

Thanks in advance! By the way, love this forum! Every question I have had so far has been answered! Incredible!

/MightyBob

mehtapratik
mehtapratik

Member

Member

269 points

302 Posts

Re: Abort binding in ConvertBack method & Getting DataContext

 for the second question, you can use like this, it's not a good way, but i am doing in the following way.

 

   public class ValueConverter : System.Windows.Data.IValueConverter
    {
        PermissionTypes objPermissionTypes;
        public ValueConverter()
        {
            if (objPermissionTypes == null)
                objPermissionTypes = new PermissionTypes();
        }

        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Int32 intCounter = 0;
            for (int i = 0; i < objPermissionTypes.PermissionTypeList.Count; i++)
            {
               
                if (objPermissionTypes.PermissionTypeListIdea.id == (int)value)
                {
                    return objPermissionTypes.PermissionTypeListIdea;
                }
                intCounter++;
            }
            return null;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
        
            return ((BWS.PermissionTypeService.PermissionType)value).id;
        }
        #endregion
    }

Pratik Mehta
Espirit Softwares Pvt. Ltd.
India.

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Re: Abort binding in ConvertBack method & Getting DataContext

In regards to Question 1, could I somehow pass the textbox itself as a parameter? Would that work, and if so, how would I do that?

<TextBox x:Name="txtTo"
  Text="{Binding ElementName=txtFrom,
  Path=Text, ConverterParameter=[****THIS TEXTBOX****],
  Converter={StaticResource Converter}}"

Anyone?

mehtapratik
mehtapratik

Member

Member

269 points

302 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

 may be you have to pass old value so if the value is not matched with your criteria you can bind it with old value.

Pratik Mehta
Espirit Softwares Pvt. Ltd.
India.

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

mehtapratik:

 may be you have to pass old value so if the value is not matched with your criteria you can bind it with old value.

Sure, sounds good, but how do I pass the old value? And, maybe you know how to pass the entire TextBox so I could access the DataContect value too?

/MightyBob

sbrato
sbrato

Member

Member

258 points

44 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

Hello,

It seems to me that the converters you are creating are doing more than they should (but I may not fully understand your requirements). A converter used in a bindind should just convert values from one type to another and it's not the place to do validation or other datacontext object updates.

For your second question, when a UI control is databound to a property in a dataContext, the binding will call the setter for that property when the input in the UI control changes. Therefore, for your example, when the Salary of a person receives a good value, the setter will get called, and it's in that setter that you should update other fields like SalaryDate. It's not clear to me why whould you make these updates in the Converter.

For the first question, it seems you want to do validation in the converter code. If you decide in the converter that you cannot convert, you should return back the same object. Back to the Salary example.. if you get an object in the converter that cannot be converted to a float, just return it back unconverted. The binding engine will fail to call the Salary property and it will raise BindingValidationError event (if you set NotifyOnValidationError=true and ValidatesOnExceptions=true). You can then handle BindingValidationError and do whatever you want there (including reverting back the value by just settign the Text on the TextBox to the value of the Salary property (which note that it didn't get changed since the binding engine failed to call the constructor).

BTW, Silverlight 3 beta includes build-in validation support. In your case, if something invalid is passed to the Salary text-box, the build-in validation in SL3 will automatically highlight the field and display ui error cues

Hope this helps

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

sbrato:

Hello,

It seems to me that the converters you are creating are doing more than they should (but I may not fully understand your requirements). A converter used in a bindind should just convert values from one type to another and it's not the place to do validation or other datacontext object updates.

For your second question, when a UI control is databound to a property in a dataContext, the binding will call the setter for that property when the input in the UI control changes. Therefore, for your example, when the Salary of a person receives a good value, the setter will get called, and it's in that setter that you should update other fields like SalaryDate. It's not clear to me why whould you make these updates in the Converter.

For the first question, it seems you want to do validation in the converter code. If you decide in the converter that you cannot convert, you should return back the same object. Back to the Salary example.. if you get an object in the converter that cannot be converted to a float, just return it back unconverted. The binding engine will fail to call the Salary property and it will raise BindingValidationError event (if you set NotifyOnValidationError=true and ValidatesOnExceptions=true). You can then handle BindingValidationError and do whatever you want there (including reverting back the value by just settign the Text on the TextBox to the value of the Salary property (which note that it didn't get changed since the binding engine failed to call the constructor).

BTW, Silverlight 3 beta includes build-in validation support. In your case, if something invalid is passed to the Salary text-box, the build-in validation in SL3 will automatically highlight the field and display ui error cues

Hope this helps

 

Hi sbrato,

Thanks for your input! To be honest, I was not aware of setters. I'm pretty new to Silverlight. If I have a datagrid bound to a collection of Persons, couls you show me how to apply the logic you suggested? What I want, is if someone alters the salary for the person in the datagrid (editable textbox), I want the value of Person.salary_date (datetime) to be set to the current date.

Regards,

MightyBob

sbrato
sbrato

Member

Member

258 points

44 Posts

Answered Question

Re: Re: Abort binding in ConvertBack method & Getting DataContext

Hello,

To get an understanding on how the databinding works (this in not realated with dataGrid.. it's applicable to all the controls) please take a look at http://silverlight.net/learn/tutorials/databinding.aspx .

When you databind a DataGrid to a collection of items, every row represent an item in that collection, and every cell maps to a certain property on that Item. In your's case, the cell for the salary is dataBound to the Salary property defined in your Person class. When you edit the cell and supply a valid value, the setter for the Salary gets called and it's there where I would say it's the best place to update SalaryDate. For e.g.

    public class Person
    {
        public float Salary
        {
            get
            {
                return _salary;
            }
            set
            {
                _salary=value;
                SalaryDate=DateTime.Now;
            }
        }

        public DateTime SalaryDate
        {
            get;
            set;
        }
    }
 

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

sbrato:

Hello,

To get an understanding on how the databinding works (this in not realated with dataGrid.. it's applicable to all the controls) please take a look at http://silverlight.net/learn/tutorials/databinding.aspx .

When you databind a DataGrid to a collection of items, every row represent an item in that collection, and every cell maps to a certain property on that Item. In your's case, the cell for the salary is dataBound to the Salary property defined in your Person class. When you edit the cell and supply a valid value, the setter for the Salary gets called and it's there where I would say it's the best place to update SalaryDate. For e.g.

    public class Person
    {
        public float Salary
        {
            get
            {
                return _salary;
            }
            set
            {
                _salary=value;
                SalaryDate=DateTime.Now;
            }
        }

        public DateTime SalaryDate
        {
            get;
            set;
        }
    }

 

 

Hi sbrato,

Ah, now I see. How beautifully simple! I guess the most simple answers are the ones you get caught up on the most ha? ;) I will try it immediately, but I'm sure it will be just what I need. Oh, and I'm sorry for seeming a bit confused in my earlier post, I thought you were talking about setters in XAML (the ones you use for templates and so, I think, I haven't been able to read up on those yet), not property get/set. Duh... Hahaha! Anyways, thanks! I'll give it a try at once.

/MightyBob

MightyBob
MightyBob

Member

Member

12 points

44 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

Hi sbrato,

It worked like a charm!

Thanks alot!

silverstarter
silverst...

Member

Member

216 points

146 Posts

Re: Re: Abort binding in ConvertBack method & Getting DataContext

 

ok, to make it a little bit more complicated:

what if i bind a datevalue and use a string-datetimeConverter?

the problem is.. it can be a wrong syntax like 17.70 or even a word instead of time.. how can i write back the old value into the textbox if it was wrong?

 

ty

silverstarter

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities