Bind command on IsChecked RadioButton property - xaml

I'm using Xamarin.Forms 5 and I need to bind a Command to IsChecked radioButton property.
How can I do this?
I tryed to add a behavior on IsFocused event, since IsChecked event doesn't exist, like so, but nothing happens:
<RadioButton.Behaviors>
<behaviors:EventToCommandBehavior EventName="IsFocused" Command="{Binding ChangeStateCommand}" CommandParameter="V"/>
</RadioButton.Behaviors>

If you want to run a command upon state change then you can use the event CheckedChanged
<RadioButton>
<RadioButton.Behaviors>
<behaviors:EventToCommandBehavior EventName="CheckedChanged" Command="{Binding ChangeStateCommand}" CommandParameter="V"/>
</RadioButton.Behaviors>
</RadioButton>

Related

how to disable auto tab after pressing enter and losing focus of textbox

I have an Event Handler for a keyDownEvent in a TextBox. Now when I press Enter this Event Handler changes the Visibility to Collapsed and the TextBox hides. the Problem with it is that this obviously unfocus the TextBox and foucus sth. else in my App. How can I disable this autofocus of another element and focus nothing?
I have tried the following but i am really screwed.
if (e->Key == Windows::System::VirtualKey::Enter) {
this->mode = ITEM_MODE::SELECT; // will Change Visibility to Collapsed
FocusManager::TryMoveFocus(FocusNavigationDirection::None);
e->Handled = true;
}
Thanks for your help! <3
how to disable auto tab after pressing enter and losing focus of textbox
Derive from official document,
UseSystemFocusVisuals used to get or set a value that indicates whether the control uses focus visuals that are drawn by the system or those defined in the control template.
You could set control UseSystemFocusVisuals property as False. Then next control will not be focused by system.
<StackPanel Orientation="Vertical" Name="RootLayout" IsTapEnabled="False" >
<TextBox HorizontalAlignment="Stretch" Height="44" KeyDown="TextBox_KeyDown" />
<Button Content="FouceElement" UseSystemFocusVisuals="False"/>
<Button Content="NextBtn" UseSystemFocusVisuals="False"/>
</StackPanel>
In case you just don't want the auto-focused item to have focus indicator shown, you can change the Focus type to FocusState.Pointer.
Example (C#):
object focusedElement = FocusManager.GetFocusedElement();
((Control)focusedElement).Focus(FocusState.Pointer); // This will hide focus indicator

Bind CommandParameter to SelectedItem of GridView

I work an a Windows 8 application which shows a GridView on one page. When ever the user selects an item of this grid and clicks on a button, the next page is loaded with detail information of the selected item.
I am using MVVM for this and have a DelegateCommand from Prims:
public DelegateCommand<Route> ShowRouteDetailsCommand { get; private set; }
This command is initialized inside the constructor:
this.ShowRouteDetailsCommand = new DelegateCommand<Route>(this.ShowRouteDetails);
The navigation is done by Prisms navigation service:
private void ShowRouteDetails(Route route)
{
this.NavigationService.Navigate(PageNames.RouteDetails, route.Id);
}
The routes are shown inside a GridView:
<GridView x:Name="RouteGrid"
ItemsSource="{Binding Routes}"
SelectionMode="Single">
<GridView.ItemTemplate>
<DataTemplate> ...
The command is currently added inside the app bar (just for testing):
<AppBarButton Command="{Binding ShowRouteDetailsCommand}"
CommandParameter="{Binding SelectedValue,
ElementName=RouteGrid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Icon="Forward" />
My problem is, that the parameter of ShowRouteDetails is allways empty. It doesn't even matter if I try GridViews SelectedValue or SelectedItem property.
I know that I could easily add a SelectedRoute property, bind the SelectedItem to it and use it in ShowRouteDetails but this seems dirty to me.
Why don't you just create a var in your viewModel and bind it to the SelectedItem of the gridView? In this way, when you run the command, you have only to read the value of that var.
<GridView x:Name="RouteGrid" ItemsSource="{Binding Routes}"
SelectionMode="Single" SelectedItem="{Binding myVar}">
<GridView.ItemTemplate>
<DataTemplate>

Prism MVVM pattern: View is always one step behind on property change in ViewModel

In Prism , MVVM, Windows 8.1 StoreApp I want the ViewModel to capture the SelectItem in a ListView. The ListView contains an ObservableCollection of objects. The ViewModel needs to lookup more details of the selected object and notify the View. The View in turn should show the details of the object.
I have implemented this, but the View allways shows the former object (after selecting a new one)
Of course what I'm looking for is an immediate and correct reaction in the View on selecting an object. Here are my codesnippets, all in VB code.
EDIT: I have put up another - smaller- example, using this approach. I made a recording of the process in this video. Please take a look at it before you read further!!
The objects come from the ViewModel as:
Public Property Persons As New ObservableCollection(Of Person)
They are bound to a usercontrol:
<Grid>
<ListView
ItemsSource="{Binding Persons}"
ItemTemplate="{StaticResource BusinessCard}">
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="SelectionChanged">
<Behaviors:ListViewSelectionChangedAction/>
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</ListView>
</Grid>
Via the Behavior eventually this ends up in the ViewModel through this code:
Sub New(InjectedEventAggregator As IEventAggregator)
LocalEventAggregator = InjectedEventAggregator
LocalEventAggregator.GetEvent(Of PersonIsSelectedEvent)().Subscribe(AddressOf HandlePersonIsSelected, True)
This event is handled by this routine
Public Sub HandlePersonIsSelected(ByVal SelectedPerson As Person)
ActualPerson = SelectedPerson
End Sub
The last part of all this is the property that contains the ActualPerson like so:
Private Property _ActualPerson As Person
Public Property ActualPerson As Person
Get
Return _ActualPerson
End Get
Set(value As Person)
SetProperty(_ActualPerson, value)
End Set
End Property
EDIT: and this is the XAML that should show the selected ActualPerson:
<StackPanel DataContext="{Binding ActualPerson}" >
<Image Source="{Binding Photo}" Stretch="Fill" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text="{Binding FamilyName}" />
<TextBlock Text="{Binding Gender}" />
</StackPanel>
</StackPanel>
When I step through the code, I can see that the SelectedItem event is caught in the ViewModel, the handler for the selected person is called, the property is updated. Using Prism this would also mean, that the NotifyPropertyChanged event is fired. It IS fired indeed, otherwise the former object would not show either I guess.
But why is the View not updated immediatelty with the right (Person) object?
If you have a clue.... be my honored guest!
Regards
Let me try to understand what you said in "no reaction on the View". Are you saying the UI is NOT CHANGED, even though the 'ActualPerson = SelectedPerson' is called?
The controls have a binding property called MODE which decides the data flow. The MODE for the TextBlocks that display the Person information can be OneWay. It is possible that the binding is OneTime which is causing the issue.
Can you please confirm what is coming from your Repository? I'm assuming it isn't an observable collection. At least it shouldn't be, I'd think it would be a serialisable POCO object. This means that you will need to add the items to the observable collection. The way I do this if not using a CollectionView is to have a readonly variable of type ObservableCollection, which is never changed. Then when you make the request to messages, I would ensure the collection is cleared, ready for new the new items. Once the messages are returned, loop through each model item (message) within the response and convert them to MessageViewModels (a new class that contains bindable properties and validation (data annotations) as required. As each ViewModel item is created it is added to the observablecollection. The act of adding items to the collection will raise an event the listview is listening for and therefore will display the item (as long as the MessageViewModel has an associated data template.
private readonly _messages = new ObservableCollection<MessageViewModel>();
Public ObservableCollection<MessageViewModel> Messages {get { return _messages;}}
OnNavigateTo
Messages.Clear;
foreach(var message in await _messageRepository,GetMessagesAsync())
{
Messages.Add(new MessageViewModel(){Name = message.Name, Text = message.Text});
}
Does that make sense?
One bad solution, but maybe it is helpful. You can call "again" OnProperyChanged. I say "again" because it is supposed that SetProperty calls it, but I am having some issues with VB.NET and SetProperty too.
Private Property _ActualPerson As Person
Public Property ActualPerson As Person
Get
Return _ActualPerson
End Get
Set(value As Person)
SetProperty(_ActualPerson, value)
OnPropertyChanged("ActualPerson")
End Set
End Property
Edited 04/02/15: the good solution is here: OnPropertyChanged not fired when SetProperty is called
As simple as removing the word "Property" in the private declaration. It is because it is passed ByRef, so it cannot be a property.

How to make button bound to ICommand enable/disable when text changes, as opposed to losing focus of TextBox

I have a Windows Store XAML app with a "Save" button, which points to an ICommand property in my ViewModel.
<Button Content="Save"
Command="{Binding DataContext.SaveNewNote, ElementName=grid, Mode=OneWay}"
CommandParameter="{Binding DataContext.CurrentItem, ElementName=grid}" />
on the propertychanged event of my Note model, that fires the CanExecutedChanged event - every time (every keystroke). However, this button will only enable/disable once I leave focus of one of the related textboxes.
In other words, there is a "Name" textbox. If String.IsNullOrWhiteSpace(Name.Text), then CanExecute is set to false. This seems to execute with every keystroke.
I would expect to see this bound Save button enable and disable with each keystroke. HOWEVER, instead, I see the button enable/disable only when I tab out of the textbox.
How can I get this bound button to respect the CanExecuteChanged event on every keystroke, instead of when the texbox loses focus?
The comments by #will and #patrick on the original post both had the correct answer. To do this, you must set the "UpdateSourceTrigger" to "PropertyChanged" and that gives the intended results.
<TextBox Grid.Row="1" PlaceholderText="Enter a short description here"
Text="{Binding NoteAbstract, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}">
</TextBox>

Access Bound Data in ListBox.ItemTemplate using Custom Control (Silverlight 4)

I Have a ListBox and I am defining its ItemsTemplate using a custom control. I want the control to be displayed in different ways depending on the state of cetain properties of the object. How can I access the item that the ListBox.ItemTemplate is bound to?
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<custom:MyControl />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
With in the code of the custom control how would I do something like:
if((this.DataContext as SomeObject).CollectionProperty.Count() > 0)
DoAction();
I was accessing dataContext in the constructor and it was null. I accessed it in the this.Loaded event and it worked fine.