View:
TextBox x:Name="feedback" Text="{Binding FeedbackText,Mode=TwoWay}"
ViewModel:
public string FeedbackText
{
get
{
return _feedbackTextProperty;
}
set
{
_feedbackTextProperty = value;
RaisePropertyChanged(FeedbackTextPropertyName);
}
}
I am using a bindable application bar but when I click the button there is no value in the FeedbackText property. It looks as if "lostfocus" is not firing to update the property.
I am using MVVM Light. Have I missed something?
If you still had focus in the textbox when you clicked the app bar button the textbox won't fire the lost focus event and cause teh binding to update.
Yes, this can be frustrating. :(
There are various work arounds such as forcibly updating the binding in such a situation or the Binding Helper in the Coding4Fun Tools.
I hope that I am not too late. I had the same problem using Window Phone 8 saving the TextBox text when pressing an ApplicationBarIconButton. A way to fix this issue is to update the binding source property of the focused TextBox. You can do that with the following code:
var focusedObject = FocusManager.GetFocusedElement() as TextBox;
if (focusedObject != null)
{
var binding = focusedObject.GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
Best!
Related
I am using Prism and Autofac with Xamarin.Forms 4.0 with an MVVM architecture. Using the Navigation.NavigateAsync("MyPage") works unless I have a binding to the Date object with my ViewModel.
The page renders properly and I am navigated to it if my DatePicker has no binding.
<DatePicker x:Name="ProcessStartDate" Format="D" MinimumDate="01/01/2000" />
However the following will cause me to never navigate to the page.
<DatePicker x:Name="ProcessStartDate" Format="D" MinimumDate="01/01/2000" Date="{Binding SelectedStartDate, Mode=TwoWay}"
The property in the View Model, MyVM, looks like this.
private DateTime selectedStartDate;
public DateTime SelectedStartDate
{
get
{
return selectedStartDate;
}
set
{
SetProperty(ref selectedStartDate, value);
sample.ProcessStartDate = value;
}
}
Navigation with the following code fails with the Binding in XAML above:
INavigationResult status;
try
{
var parameters = new NavigationParameters();
parameters.Add("CurrentSample", SelectedSample);
status = await NavigationService.NavigateAsync("MyPage", parameters); //MyPage is registered with MyVM
}
catch (Exception ex)
{
string mess = ex.Message;
}
My work-around is to add an event handler to the code-behind.
<DatePicker x:Name="ProcessStartDate" Format="D" MinimumDate="01/01/2000" DateSelected="OnStartDateSelected"
So now my code-behind has a handler:
void OnStartDateSelected(object sender, DateChangedEventArgs args)
{
SampleDetailsViewModel vm = BindingContext as SampleDetailsViewModel;
vm.SelectedStartDate = args.NewDate;
}
I have a work-around for this page, But I don't want put code in the code-behind. This breaks the MVVM standard that I've managed to maintain on the other seven pages of the app. Am I Binding improperly with the DatePicker?
When Binding SelectedStartDate, you are not initializing it, making it binding to a null, because you have set the Binding Mode to "TwoWay".
Here you can find the various types of binding modes, quoting:
Causes changes to either the source property or the target property to
automatically update the other. This type of binding is appropriate
for editable forms or other fully-interactive UI scenarios.
a solution would be something like this (if you wanna keep the TwoWay mode, and dont mind starting with an default selected):
private DateTime selectedStartDate = DateTime.Now;
Or
Making the binding mode to "OneWayToSource", this makes updates to the binding source without, and not the target (remember that this way you can't change the selected date from the binding, only the datepicker can).
Updates the source property when the target property changes.
Or
If you wanna keep the TwoWay Mode and not having a default date selected, the way you did with code behind is a nice workaround.
I have a list view that I am popping up in Xamarin forms, that I want to hide if someone taps outside of the box. I have a tap gesture recognizer on the parent layout for the list view that handles that. In Android, it all works good. If I click off, it closes, but if I click on an element in the list view, it properly selects it. In iOS, the opposite happens. The gesture handler on the layout fires first and closes the list view without properly selecting the item.
So my question, is there a way to change the order on how the events are fired? If not, is there a better alternative to how I'm trying to accomplish this? Thanks!
If you are using ListView.ItemSelected or ListView.ItemTapped then I ran into the exact same issue the other day. The fix for me was to not use either of those and instead attach a TapGestureRecognizer to the ViewCell that is within the ListView. I also added an IsSelected property to the object that the ViewCell is being bound to so that I could change the background color of the item once it has been clicked.
public class SomePage : ContentPage {
private SomeModel _selectedModel; //It would be best to put this into your ViewModel
...
public SomePage() {
ListView list = new ListView {
ItemTemplate = new DataTemplate(() => {
ViewCell cell = new ViewCell {
View = new ContentView()
};
cell.View.GestureRecognizers.Add(new TapGestureRecognizer {
Command = new Command(() => {
if(_selectedModel != null) { _selectedModel.IsSelected = false; }
SomeModel model = (SomeModel)cell.BindingContext;
model.IsSelected = true;
_selectedModel = model;
})
}
return cell;
}
}
}
}
I have developed a user control which has only a RadComboBox with checkbox enabled in it. The problem that I am facing in my pages is, whenever I deselect all the checkbox items with in the RadComboBox and on close of it, the last selected item is displayed in its text section. I am not finding a way to fix it.
In the ideal scenario, if nothing / everything is selected, I am defaulting to the text "All". If any item is selected, the item text is displayed. Can some one help me, if I have to do any specific check to fix this problem?
I am sharing a animated GIF for my issue below.
Thanks,
Sriram
I also got the same issue. But I solved as following.
Creative a property in your userControl as:
public string OnClientItemChecked {
set { ddlControID.OnClientItemChecked = value; }
}
on aspx:
<uc1:TagName ID="ddlControlID" runat="server" OnClientItemChecked="ClearValue" />
on script tag:
function ClearValue(sender, eventArgs) {
var combobox = sender;
var value = combobox._checkedIndices.toString();
if (value == "") {
combobox.clearSelection();
combobox.set_emptyMessage(combobox.get_emptyMessage());
}
}
on aspx:
Do AllowCustomText="True" in your RadComboBox.
I'm using the TextBoxValidationExtension in a MVVM pattern. I was having a problem with the validation because I'm setting my binding source in TwoWay mode in the NavigatedTo method which is called after the TextBoxFormatValidationHandler.Attach method is called. The first validation therefore occurred with empty value on the textbox which was applying the error styling to the textbox.
The binding in the NavigatedTo to the Text property of the textbox wasn't triggering a Textbox TextChanged event since from my comprehension the Textbox control is not loaded at this point.
So even tough I had a valid value binded to the textbox it appears to be invalid since the extensions didn't validated it.
<TextBox Text="{Binding Path=ObjectXYZ.PropertyABC, Mode=TwoWay}"
extensions:TextBoxFocusExtensions.AutoSelectOnFocus="True"
extensions:FieldValidationExtensions.Format="NonEmpty,Numeric">
What I've done to solve the problem was to add to the WinRT Toolkit TextBoxFormatValidationHandler a handler to the loaded event of the textbox in the TextBoxFormatValidationHandler.Attach method:
internal void Attach(TextBox textBox)
{
if (_textBox == textBox)
{
return;
}
if (_textBox != null)
{
this.Detach();
}
_textBox = textBox;
_textBox.TextChanged += OnTextBoxTextChanged;
_textBox.Loaded += _textBox_Loaded;
this. Validate();
}
void _textBox_Loaded(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
this.Validate();
}
If someone has a better solution can you please let me know, thanks!
I'm trying to bind CheckedChange from monodroid CheckBox to a command, but I get an error.
I want to unselect another item when a particular one is checked.
I think it is possible to do it with EventTrigger in wp7, but MvvmCross for android doesn't seem to support this feature.
Is MvvmCross limited to Button only ?
Thanks in advance for your help.
CheckedChanged is an EventHandler<CompoundButton.CheckedChangeEventArgs> so it isn't one of the delegate types that MvvmCross automatigically knows about.
However, there is a custom binding in place for this...
https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/Target/MvxCompoundButtonCheckedTargetBinding.cs
And this custom binding should be registered using:
registry.RegisterFactory(new MvxSimplePropertyInfoTargetBindingFactory(typeof(MvxCompoundButtonCheckedTargetBinding), typeof(CompoundButton), "Checked"));
in https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Binding.Droid/MvxAndroidBindingBuilder.cs
So if you have a ViewModel with a property IsSpecial
private bool _isSpecial;
public bool IsSpecial
{
get { return _isSpecial; }
set
{
_isSpecial = value;
RaisePropertyChanged(() => IsSpecial);
// your custom code here
}
}
then this binding should work:
'Checked':{'Path':'IsSpecial'}
And that should work for any CompoundButton - CheckBox, Switch, or your own compounds...