I have a checkbox in silverlight and I have binded the checkbox IsChecked property with one string property which stores the value like 'True' and 'False'. I have used a converter in the binding to convert the string value to bool. I also have the event handler for checkbox 'checked' and 'unchecked' event.
When I checked or unchecked the checkbox , binding update as well as the handler for the checkbox ''checked' and 'unchecked' event is called but hanlder is called first and then binding updates. But I require checkbox to update the binding first (for IsChecked property) and then the event hanlder to get called. How can I achieve this.
// property with which I am binding IsChecked property is 'PropertyPath'
// binding code
CheckBox checkBoxControl = new CheckBox();
Binding binding = new Binding();
binding.FallbackValue = false;
binding.Mode = BindingMode.TwoWay;
binding.Source = this;
binding.Converter = new BoolStringToBoolConverter();
binding.Path = new PropertyPath("PropertyPath");
checkBoxControl.SetBinding(GenericCheckBox.IsCheckedProperty, binding);
checkBoxControl.Checked += new RoutedEventHandler(checkBox_CheckedProperty_Changed);
handler
void checkBox_CheckedProperty_Changed(object sender, RoutedEventArgs e)
{
CheckBox chkBox = sender as CheckBox;
// Here the value of 'PropertyPath' is not updated as binding is not updated yet
}
below is the converter I am using in binding
public class BoolStringToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value.ToString().ToUpper().Trim().Equals("TRUE"))
{
return true;
}
else
{
return false;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null && value.GetType().Equals(typeof(bool)) && (bool)value)
{
return "True";
}
else
{
return "False" ;
}
}
}
On clicking the checkbox the event handler is getting called first and then 'ConvertBack' method of converter gets called and hence in the event handler I dont get the updated value of property 'PropertyPath'.
How can I make sure to call the binding updates before calling the checkbox event handler.
Related
I have created custom data type based on built-in dropdown list, but cannot figure out how to specify default value for the list. The default value is always blank:
The default dropdown does not support default value
There is two way of achieving what you want
create your own dropdown datatype (or use a plugin someone else has made - I am not sure which one support it, but maybe have a look at nuPickers )
since it is your custom made you can control it. More about how to create one checkout doc Tutorial - Creating a property editor
use a web api handler to intercept the call of getting the content value - and set a default value to your property if it is empty (null)
below is some un-tested code:
first create the web api handler
public class SetDropdownDefaultHandler : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync
(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
var url = request?.RequestUri?.AbsolutePath.ToLower;
// only process when a create (getempty) or editing a specific content (getbyid)
if (url == "/umbraco/backoffice/umbracoapi/content/getempty"
|| url == "/umbraco/backoffice/umbracoapi/content/getbyid")
{
var content = (ObjectContent)response.Content;
var data = content?.Value as PagedResult<ContentItemBasic<ContentPropertyBasic, IContent>>;
if (data?.Items != null)
{
var tempResult = data?.Items?.ToList();
foreach (var item in tempResult)
{
foreach (var prop in item?.Properties?.Where(p => p?.Editor == "Umbraco.DropDown"))
{
var propStr = prop.Value?.ToString();
if (!propStr.IsNullOrWhiteSpace())
{
// set your default value if it is empty
prop.Value = "your default option prevalue id";
}
}
}
data.Items = tempResult;
}
}
return response;
}
}
then register it at started event
public class UmbracoEvent : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
GlobalConfiguration.Configuration.MessageHandlers.Add(new SetDropdownDefaultHandler());
}
}
your problem maybe you don't know your prevalueid - you can look it up in db or you could use datatype service to get the datatype prevalues then decide which to put as default
Look at: FieldType.DropDownList in the fieldTypes folder.
Replace:<option value=""></option>
With:
var settings = Model.AdditionalSettings;
<option value="">#settings["DefaultValue"]</option>
Then ensure you set the default value property in your dropdown list in the Umbraco Forms backoffice for the given form
If I get the value of a valueChangeListener on a PickerField it returns null if I choose the same customer the second time.
Is it a vaadin bug?
#Named("fieldGroup.customer")
PickerField customer;
#Override
public void init(Map<String, Object> params) {
super.init(params);
customer.addValueChangeListener(e -> {
if (e.getValue() != null) {
showNotification("e.value: " + e.getValue(), NotificationType.HUMANIZED);
} else {
showNotification("e.value is null", NotificationType.ERROR);
}
});
}
I've created a example-project on GitHub
For now PickerField LookupAction calls setValue() method twice (with null value and with the selected) if the new item has the same id as current to ensure that previous item will be replaced with the new. That leads to two calls of ValueChangeListener with null and then with the new value.
It is a known API issue of CUBA and we will try to change it may be in the next major release of the platform, but now you have to check for null e.getValue() and entity attribute that is bound to a PickerField.
when my model property is declared with not null able date-time then no problem occur when we check data type of property but the moment i have a null able date time property then the below code return false
if (datatype.GetType().Equals(new DateTime().GetType()))
{}
here is full code
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
ValidationResult validationResult = ValidationResult.Success;
try
{
// Using reflection we can get a reference to the other date property, in this example the project start date
var containerType = validationContext.ObjectInstance.GetType();
var field = containerType.GetProperty(this.otherPropertyName);
var extensionValue = field.GetValue(validationContext.ObjectInstance, null);
var datatype = extensionValue.GetType();
//var otherPropertyInfo = validationContext.ObjectInstance.GetType().GetProperty(this.otherPropertyName);
if (field == null)
return new ValidationResult(String.Format("Unknown property: {0}.", otherPropertyName));
// Let's check that otherProperty is of type DateTime as we expect it to be
if (datatype.GetType().Equals(new DateTime().GetType()))
{
DateTime toValidate = (DateTime)value;
DateTime referenceProperty = (DateTime)field.GetValue(validationContext.ObjectInstance, null);
// if the end date is lower than the start date, than the validationResult will be set to false and return
// a properly formatted error message
if (toValidate.CompareTo(referenceProperty) < 1)
{
validationResult = new ValidationResult(ErrorMessageString);
}
}
else
{
validationResult = new ValidationResult("An error occurred while validating the property. OtherProperty is not of type DateTime");
}
}
catch (Exception ex)
{
// Do stuff, i.e. log the exception
// Let it go through the upper levels, something bad happened
throw ex;
}
return validationResult;
}
get me the idea of best fix because my property should be null able date time fields. thanks
Your variable field (returned by call GetProperty) is type PropertyInfo so if you want the type withotu going to the value you need to call property PropertyType.
if (field.PropertyType == typeof(DateTime) || (field.PropertyType.IsGenericType && field.PropertyType == typeof(Nullable<DateTime>))) { }
Here is the reference for PropertyInfo.
You should convert your type checks to typeof(TypeHere) instead of new TypeHere.GetType(). The former does not have to create a new instance which could be expensive if the code is repeated / looped many times. See my example.
Also take #David's (the other answer) advice about using throw; instead of throw ex;. The later will reset the entire captured exception call stack.
It's not really clear why you're comparing the types and not the values, but I guess that's beside the point. In this comparison:
datatype.GetType().Equals(new DateTime().GetType())
This is going to return true if datatype is of type DateTime. So, reasonably, it will not return true if datatype is of some other type, such as Nullable<DateTime>.
You should be able to compare with that type instead:
datatype.GetType().Equals(new Nullable<DateTime>().GetType())
Or perhaps with both:
datatype.GetType().Equals(new DateTime().GetType()) ||
datatype.GetType().Equals(new Nullable<DateTime>().GetType())
Side note: Your catch block is entirely superfluous and is actually removing information about the exception. It's something of an anti-pattern and should be removed entirely. If you are actually handling the exception in any way in that catch block and do want to re-throw, just use throw; instead of throw ex;.
You cannot check the type of a null value therefore you need to check if it's null before you do anything else.
if(datatype == null)
validationResult = new ValidationResult(ErrorMessageString);
else if (datatype.GetType() == typeof(DateTime))
{
if(!IsValidDate(datatype.Value))
validationResult = new ValidationResult(ErrorMessageString);
...
}
I'm creating a new message, by setting the indexers, like:
Iso8583 isoMsg = new Iso8583();
isoMsg[field] = value;
I noticed that I'm not receiving any exceptions; following the code I've seen that the validator is not running when I'm setting the fields this way; it only executes when unpacking a byte[] message. Do you think it would be possible to adapt the format and length validators to run also when setting a field?
Thanks in advance!
The validators are run on the fields when you call .Pack() on the message.
I guess you just set the value to one of the existing fields form the default template
When you create Iso8583() it uses the DefaultTemplate, which adds the set of default fields into the message instance on creation.
Indexer property is derived from AMessage class, which is Iso8583 class is inherited from.
public string this[int field]
{
get { return this.GetFieldValue(field); }
set { this.SetFieldValue(field, value); }
}
These methods:
protected string GetFieldValue(int field)
{
return this.bitmap[field] ? this.fields[field].Value : null;
}
protected void SetFieldValue(int field, string value)
{
if (value == null)
{
this.ClearField(field);
return;
}
this.GetField(field).Value = value;
}
So it seems that your code sets the value for one of the field from the default template
isoMsg[field] = value;
I have a combobox, that I populate from a web service:
public Configure()
{
InitializeComponent();
WebServiceSoapClient ws = new WebServiceSoapClient();
ws.GetTypesCompleted += new EventHandler<GetTypesCompletedEventArgs>(OnGetTypeCompleted);
ws.GetTypesAsync();
}
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
}
}
So when I set the ItemSource property, SelectionChanged event gets fired with SelectedIndex = 0, but user hasn't made this selection yet and I need this list to have no selected value, so I'm setting SelectedIndex to -1, as you can see. As a result, SelectionChanged is called twice.
Can I make it be called only when user selects the item?
Thanks!
I'm using Silverlight 3 and VS 2008
Instead, modify your code so that the SelectionChange event handler isn't defined until after the itemssource and selected index are set.
void OnGetTypeCompleted(object sender, GetTypesCompletedEventArgs e)
{
if (e.Result != null)
{
List<CodeTableItem> source = e.Result.ToList<CodeTableItem>();
lstType.ItemsSource = source;
lstType.SelectedIndex = -1;
lstType.SelectionChanged += new SelectionChangedEventHandler(lstType_SelectionChanged);
}
}
In our application we implemented some code that would set a boolean flag based on the Control.LeftMouseButtonUp() event. When this has been set, it would mean that the user has interacted with the field, and so we can handle the SelectionChanged with different behaviour.
Over the development lifetime of our application this approach was essential so that default bindings would trigger our SelectionChanged logic when we didn't want it to.
If you are an MVVM purist, you'll need to expose the VM as a member variable and then set the bool flag in the VM.
HTH,
Mark