Set Focus OnNavigatedTo in Prism for WPF Application - wpf

I would like on navigation between views in a WPF application using Prism to have the ability to set focus to sepecific textboxes so a user can perform navigation and then begin typing in the relevant textbox without a second click into the textbox.
I have an application built with Prism that has a Shell with a ContentControl "MainContentRegionContentControl". I then have some buttons across the top when on clicking them I do a region.RequestNavigate("UserControlToLoad"). On the UserControl I have the OnNavigatedTo and in that method I call this.MainTextBox.Focus().
The above doesn't appear to work, the navigation appears to work and the OnNavigatedTo method is called, but the textbox doesn't have focus.
I've added FocusManager.IsFocusScope="True" to the textbox, but this hasn't made a difference.

Use Loaded() method for each page instead of OnNavigatedTo() and TextBox.Focus() will work fine then ;)

Try the following... In your View implement IActiveAware
class ViewModel : IActiveAware
{
#region IActiveAware Members
private bool isActive = false;
public bool IsActive
{
get
{
return isActive;
}
set
{
if (value != isActive)
{
isActive = value;
OnIsActiveChanged(EventArgs.Empty);
}
}
}
public event EventHandler IsActiveChanged = delegate { };
protected virtual void OnIsActiveChanged(EventArgs args)
{
IsActiveChanged(this, args);
}
#endregion
}
OnIsActiveChanged, try setting focus to the TextBox you'd like to focus when IsActive becomes true

Related

Xamarin Forms create a Clicked Event for CheckBox Control

so I am trying to use the CheckBox Control with MVVM logic. However the only event existing is CheckedChanged, which also triggers if I am navigating from the page for example.
I am searching for a Clicked event, like a button has.
Do I need to create a custom control with custom renderer, or is there a better solution?
Looking forward to replies.
[EDIT]
To provide more information about my issue, I will put code examples below.
My CheckBoxes are inside a ListView. Each CheckBox is defined like this in XAML:
<CheckBox
IsChecked="{Binding IsCompleted}">
<CheckBox.Behaviors>
<prism:EventToCommandBehavior
EventName="CheckedChanged"
Command="{Binding SubTaskStateChangedCommand}"/>
</CheckBox.Behaviors>
</CheckBox>
The ItemSource of the ListView has a property IsCompleted and a DelegateCommand SubTaskStateChangedCommand. It is worth mentioning that i am using Prism.
In the constructor:
SubTaskStateChangedCommand = new DelegateCommand(OnSubTaskStateChangedCommandExecuted);
Class SubTaskModel:
public DelegateCommand SubTaskStateChangedCommand { get; set; }
private void OnSubTaskStateChangedCommandExecuted()
{
//Do something
}
private bool _isCompleted;
public bool IsCompleted
{
get { return _isCompleted; }
set { _isCompleted = value; OnPropertyChanged(); }
}
So when I am navigating to another page in my ViewModel using the Prism NavigationService, the OnSubTaskStateChangedCommandExecuted Method gets triggered. However, I noticed that when this happens, the IsCompleted value DOES NOT change.

MahApps Metro- React on Tab Close in VS Styled Tabcontrol

I am using a VS styled Tabcontrol (from the MahApps.Metro Project) in a Project with the Caliburn.Micro framework and I am looking for a way to let my ViewModel which inherits from Conductor.Collection.OneActive know when a Tab is being closed. Unfortunately the close button is already included in the style, and that is confusing me a bit. I looked up in the MahApps Source files for this VS Tabcontrol style, and found that each close button is bound to a CloseCommmand (Command="{Binding Path=CloseCommand}"). How can I react to a click of that button?
Attach DeactivateItem event to the close button.
<Button cal:Message.Attach="DeactivateItem($dataContext, 'true')" />
The DeactivateItem is a framework method of caliburn micro, defined in Conductor class.
This method will close the associated view and removes the view from Conductor Collection.
FYI:
Framework method.
public override void DeactivateItem(T item, bool close) {
if(item == null || !item.Equals(ActiveItem))
return;
CloseStrategy.Execute(new[] { ActiveItem }, (canClose, items) => {
if(canClose)
ChangeActiveItem(default(T), close);
});
}
Since the CloseTabCommand will trigger the Unloaded event, My workaround is attach a handler to it.
public partial class MyTab : MetroTabItem {
public MyTab() {
InitializeComponent();
this.Unloaded += dosomthing;
}
public void dosomething(Object sender, EventArgs e) {
//Your code
}
}

How to disable a region when a child window pops up in another region in prism mef wpf

I have two regions in Shell- Toolbar region and content region.
Content region has many views- parent and child windows. When a child window pops up Toolbar region is not disabled. What should be done to disable the Toolbar region?
You can bind your viewModel's main content's attribute IsEnabled to a boolean property IsPopupGone. In the constructor of your toolbar subscribe EventAggregator to an event PopupWindowStateChanged and payload as a boolean. Then when your popup window(s) display, publish this event with True, and when closed publish as False.
private bool isPopupGone = true; // default/original state assumed to be no childs showing
public bool IsPopupGone
{
get { return isPopupGone; }
set { isPopupGone = value; /* implement notifypropertychanged */ }
}
public ToolbarViewModel(IEventAggregator eventAggregator)
{
EventAggregator = eventAggregator;
EventAggregator.GetEvent<PopupWindowStateChanged>().Subscribe(UpdateEnabledState);
}
public void UpdateEnabledState(bool isPopupShowing)
{
IsPopupGone = !isPopupShowing;
}
<UserControl x:Class="ToolbarView">
<Menu IsEnabled="{Binding Path=IsPopupShown, Mode=OneWay}">
...
</Menu>
</UserControl>
And the popup just needs to do the below when appropriate, either when created/showing (true), or when closing (false)
EventAggregator.GetEvent<PopupShowingChanged>().Publish(true); // false
I don't like the naming of the property IsPopupGone, I'd rather have IsPopupShowing and use a converter in the XAML, but this may be easier as an answer for you/others.

Can't bind to IsExpanded on Expander

Blacklight is an older set of WPF controls and styles. The code can be found here. It contains a control called AnimatedExpander which isn't really an expander, rather it just implements HeaderedContentControl and adds an IsExpandedProperty dprop:
public static readonly DependencyProperty IsExpandedProperty =
DependencyProperty.Register("IsExpanded", typeof(bool), typeof(AnimatedExpander), new PropertyMetadata(true));
public bool IsExpanded
{
get
{
if (this.expandToggleButton != null)
{
return this.expandToggleButton.IsChecked.Value;
}
return (bool)GetValue(IsExpandedProperty);
}
set
{
SetValue(IsExpandedProperty, value);
}
}
I need to bind to IsExpanded so that I can persist whether expanders are expanded. I'm pretty sure I have the binding setup correctly, and that there is a problem with this custom dependency property. If I open the view in Snoop, and set the IsExpanded=True on the expander, the binding works. However, just clicking the expandToggleButton on the control only expands the control, it doesn't hit my binding.
<controls:AnimatedExpander IsExpanded="{Binding SGGExpanderExpanded}" />
private bool _sGGExpanderExpanded;
public bool SGGExpanderExpanded
{
get { return _sGGExpanderExpanded; }
set
{
if (_sGGExpanderExpanded != value)
{
_sGGExpanderExpanded = value;
OnPropertyChanged("SGGExpanderExpanded");
}
}
}
How can I bind to a value that changes when the user clicks the toggle button that is wired to expand the control?
A bad solution:
I was able to make this work by attaching an event to the ToggleButton click and looking at the "sender" Content and IsChecked values to update my viewmodel.

WPF Inner Property Binding not updating

I have an INotifyProperty Screen item that I have bound to a wpf control.
Ok... I Simplified everything and am posting more code. I have a MainViewModel with the selected screen property.
public Screen SelectedScreen
{
get { return this.selectedScreen; }
set
{
this.selectedScreen = value;
this.OnPropertyChanged("SelectedScreen");
}
}
I have a textbox that is bound to this property:
<TextBlock Text="{Binding Path=SelectedScreen.ScreenNumber}" />
This all works initially. I have created another control that is changing the selected screen with the following code.
public Screen SelectedScreen
{
get { return (Screen)GetValue(SelectedScreenProperty); }
set
{
this.SetValue(SelectedScreenProperty, value);
for (int x = 0; x < this.Screens.Count; ++x)
this.Screens[x].IsSelected = false;
value.IsSelected = true;
}
}
public ObservableCollection<Screen> Screens
{
get { return (ObservableCollection<Screen>)GetValue(ScreensProperty); }
set { this.SetValue(ScreensProperty, value); }
}
public static readonly DependencyProperty SelectedScreenProperty =
DependencyProperty.Register("SelectedScreen",
typeof(Screen),
typeof(ScreenSelection));
public static readonly DependencyProperty ScreensProperty =
DependencyProperty.Register("Screens",
typeof(ObservableCollection<Screen>),
typeof(ScreenSelection),
new UIPropertyMetadata(new ObservableCollection<Screen>()));
This screen selection control is working. When I change screens and put a breakpoint on the set property of SelectedScreen it is called which then calls the SelectedScreen property of the MainViewModel. So the event is firing, but the textbox isn't updated even though it binds correctly the first time.
Does the class which contains the SelectedScreen property implement INotifyPropertyChanged? When the SelectedScreen property changes, the containing class should raise the PropertyChanged event, and typically, WPF should update the Binding.
Thank you gehho for looking at this. I figured it out and there is no way you had enough information to be able too. I was inheriting from ViewModelBase in the MainViewModel that was inheriting from ObservableObject where I implemented INotifyPropertyChanged. The problem is that I implemented the methods for INotifyPropertyChanged in both classes and WPF was listening to the wrong one. Very obscure. Very annoying. Very lasjkdf;ashdoh

Resources