Load WPF UserControl with user input - c#

I am still new to WPF so excuse this simple question.
But I just don't know how to load a UserControl in WPF where the user entered data.
The following scenario:
User enters data into the view and clicks Next. If he now clicks the Back button on the view, how can I display the entered data again?

As the fastest option is using property "Visibility" with onPropertyChaged.
You can create property
private Visibility m_controlUserVisibility = Visibility.Hidden;
public Visibility ControlUserVisibility
{
get { return m_controlUserVisibility; }
set
{
m_controlUserVisibility = value;
OnPropertyChanged();
}
}
and Binding in XAML
<UserControl Visibility="{Binding ControlUserVisibility}"></UserControl>
When you want show UserControl - write:
ControlUserVisibility = Visibility.Visible;

Assuming that your requirement is some form of multi-page wizard control ...
Create a set ViewModel classes, one for each page of the wizard, and set an instance of each as properties of your main ViewModel. Add a SelectedPage property and set to the initial page ViewModel. The forward / backward navigation between pages should update the SelectedPage value as appropriate. The entered data will stay in memory and will remain available as the user navigates between pages.
In the View, add a ContentControl and bind its Content property to SelectedPage, along with buttons to control the navigation between pages. Create a DataTemplate for each page ViewModel type in the ContentControl's resources, to define the UI layout for that page.

Related

MVVM-way to notify neighbour usercontrol about changes

all!
In my main window I have a Grid with 2 columns. In column 0 is a usercontrol with settings, in column 1 is usercontrol with content.
The goal is to reset usercontrol with content when settings are changed. What is the right "MVVM"-way to do it?
Both usercontrols are implemented in MVVM-way, having all business logic in ViewModels.
Say I have a CheckBox bound to a Property in the settings-usercontrol:
Settings.xaml
...
<CheckBox IsChecked="{Binding Path=MySettingNr1}">
...
In Settings_ViewModel.cs
...
public bool MySettingNr1
{
get
{
return _model.SttNr1;
}
set
{
if(_model.SttNr1 == value) return;
_model.SttNr1 = value;
OnPropertyChanged(nameof(MySettingNr1));
}
}
...
How can I notify my content usercontrol if user clicks this checkbox?
Routed event would possibly not do, because both usercontrols are neighbours in the main window grid.
The only way I thought about was to fire an event in the usercontrol with settings, catch it in main windows and call a function of the usercontrol with content. Is there a way to make this call chain shorter?
Thanks in advance.
You could use a single shared view model for the window that both user controls bind to, i.e. they both inherit the DataContext of the parent window. This way they could communicate through the shared view model directly.
If you prefer to have two different view models, one for each user control, you could use an event aggregator or a messenger to send an event/message from one view model to antoher in a loosely coupled way.
Most MVVM libraries have implemented solutions for this. Prism uses an event aggregator and MvvmLight uses a messenger, for example.
Please refer to this blog post for more information about the concept.

Caliburn.Micro - How to display multiple items in WPF View from ViewModel that inherits: Conductor<object>.Collection.AllActive

I am using Caliburn.Micro as my MVVM framework in a WPF application. I am trying to include several custom user controls in one page which change dynamically based on user interaction. I understand that the CM convention is that the View will bind to the Items property within the ViewModel.
My question is:
How do I get access to each item within the Items collection property of the ViewModel in my View?
Can I individually place each item on the parent View page as I would normally be able to do with a normal WPF Control?
The basic appearance of the view page is shown here.
View page layout
The basic ViewModel code:
public class TestViewModel : Conductor<object>.Collection.AllActive
{
public TestViewModel()
{
Items.Add(new CustomUC1ViewModel());
Items.Add(new CustomUC2ViewModel());
Items.Add(new CustomUC3ViewModel());
}
//following logic would reassign the Items collection as required
}
The ViewModels attached to Items would change dynamically based on user interaction with the parent page and the embedded user controls.
I hope the above makes sense (this is my first ever post).
I worked out the answer to my problem. By assigning my user control views as IScreen properties in the ViewModel I was able to locate the user control whereever I want in the view through naming a ContentControl to match the relevant property in the ViewModel. The relevant property in the ViewModel can be changed and the view updates accordingly if using NotifyOfPropertyChange() in the setter.
In MyViewModel:
public class MyViewModel : Conductor<object>.Collection.AllActive
{
//the user control property where MainContent = new OtherViewModel()
private IScreen _mainContent;
public IScreen MainContent
{
get { return _mainContent; }
set
{
_mainContent = value;
NotifyOfPropertyChange(() => MainContent);
}
}
}
In MyView in XAML:
<ContentControl x:Name="MainContent"/>
The Items property in the ViewModel is instead just used to manage the lifecycle of the active windows. I was able to use multiple <ContentControl x:name="ViewModelProperty"> to place custom user controls as needed and dynamically.

Set selecteditem of combobox in wpf

I have an issue that I cannot solve myself and need your support.
In my WPF-Application I have a MainWindow with some kind of navigation bar (based on System.Windows.Controls.Ribbon) and a content area.
When I click one button1 (RibbonButton), I assign a Page to the content area of the MainWindow.
In the Page I have a combobox with several values/items and I want the value to be selected that matches to the label or name of the button I pressed in the navigation.
When I press the other button in the navigation, another item should be selected in the combobox.
Unfortunately, in my button_click event that is in the code behind of the MainWindow, I am not able to access the combobox of the Page-object.
Can someone help me how to access the combobox of the Page-object within the click event of the MainWindow?
Thank you and regards
TPS
are you using MVVM?
As I read you are using code behind in your code right?, I guess you have a reference to your page I right? I think you can create a public method on the Page I, and send the value you want to be set in the commbobox through that method, then if you are using mvvm, send that value to your viewmodel property asociated with the combobox SelectedItem.
private void ribonButton_click()
{ thePageI.SetComboboxwith("this value");
.....
}
in the PageI
public void SetCombobox( string theValue){
myViewModel.SetSelectedItem(theValue);
}
Something like that

How to reload page when navigating

I am developing WPF MUI application.I navigate to another page using button onclick and print some text on page1.xaml . after i navigate using another button to print another text on page1.xaml .but i could not do that.my out put was not new text.it is early details only.can't reload page1.xaml .when navigating I pass the parameter and according to parameter print deference text on same page.can anyone help me?
this is my navigation code
var frame = NavigationHelper.FindFrame(null, this);
frame.Source = new Uri("../Content/Sale/SaleInvoice/Nested/saleNested.xaml", UriKind.Relative);
Have the page databound to a ViewModel. Once you want to refresh just create a new Viewmodel. It would make sense to have the execution of the reloading being done in a backgroudworker so your UI stays responsive. This is esspecially usefull if you are refreshing some resource from a webService or some other online source.
The Data bind to the page at the initial time to reload the page I'm using this method
On xaml page just add Loaded Property:
<UserControl x:Class="ModernUINavigationApp1.Pages.Page"
...
Loaded="OnLoad" >
Then Add event handler in code behind to make the page do whatever you want when it's loaded
private void OnLoad(object sender, RoutedEventArgs e)
{
}
Hope this help :D
Make sure your ViewModel implements INotifyPropertyChanged. If your Page1.xaml's DataContext is set to the ViewModel, and your XAML uses bindings properly, any change to the ViewModel will be reflected in the UI. You won't need to refresh anything. Just update the property in the ViewModel object.
If you update your question with example XAML and C#, I can be of more help.

Understanding of CreationPolicy

Imagine I have 2 XAML pages and a userControl: PageA, PageB, UscGeneral
PageA will bind to ViewModelA and ViewModelB
PageB will bind to ViewModelB
UscGeneral will bind to ViewModelB
Now, I'll have this UscGeneral to attached to both PageA and PageBUscGeneral will have a VisibleFlag property to handle visibility of it in pages and VisibleFlag is in ViewModelB
Now based on certain logic, I'll set the VisibleFlag = Visibility.Visible and UscGeneral will appear at the page.
Now my problem comes because UscGeneral will appear at both page, so when VisibleFlag = Visibility.Visible, this control will appear at both pages which totally makes sense. But my objective is trying to show this control only at PageB but not PageA.
I've heard that [Import(RequiredCreationPolicy = CreationPolicy.NonShared)] will helps and so I've place it at PageB's codeBehind. But what happened was, the control is not showing at both PageA and PageB
May I know how to configure it to achieve what I want?

Categories