I have a navigation app with 5 pages. I also have a usercontrol with 3 radio buttons. This usercontrol is used by all 5 pages in my app. By default the first radio button is selected. However if the user clicks the 3rd radio button and I go to another page I want my usercontrol to still show that 3rd radio button as selected. How do I go about accomplishing this task?
There are several ways you could do this. Probably the most simple way is to create a class that has a property for the selected item of the radio buttons. Add an instance of this class as a resource to the application and then bind the radio buttons to this static resource.
public class MyState
{
public string SelectedRadioValue {get;set;}
}
In the App.xaml.cs in the Application_Startup add:
var state = new MyState()
Resources.Add("myState", state);
Then in the bindings you can set:
SelectedValue="{Binding Source={StaticResource myState},Path=SelectedRadioValue}"
There are other approaches you could take as well.
Is it possible to show this control outside of the View control? It sounds like it should be placed on the MainPage.xaml outside of the place where the views are displayed. This way the one control is used and its value can be made available to all of the views.
If you are just looking to save the state of the page as the user navigates between pages then the easiest way of accomplishing this is to set:
NavigationCacheMode="Required"
in the first element of the xaml for your page.
Related
I have a Region in the top left of the WPF application which I want to be my global button bar where the user chooses which screen they want to view, and the appropriate content will then be displayed in the main region. THere will also be a sub navigation region in the top right with sub-menu options within that screen, eg if the user clicked "Maintenance" from the main menu, the sub menu would show options for New, Update, Delete, Edit etc.
What I want to have is a way to create a custom menu bar by simply specifying a list of Text button names, and ICommand/Parameter pairs for the action to invoke on button click. The natural way to do this would be have a MenuButtonViewModel class with dependency properties Title, Command and CommandParameter. One more would also be needed, IsSelected, so there is some visual way for the user to see which screen you are currently on, so it needs to behave like a toggle button, but where only one button in the group can be selected at a time. I can then have a UserControl where the content of the bar binds to an ObservableCollection and uses data templates to render the button bar.
I have tried a few ways of doing this so far but cannot figure out a way that gives me the visual behaviour I want. These are my requirements
1) Button to change background to a different Brush OnMouseOver
2) When button is selected, a different Brush is displayed as the background until a new button in the group is selected, like a togglebutton IsSelected behaviour
3) Only one button in the group can be selected at a time
The ways I have tried to do this so far are
1) Extending RadioButton with my own class, adding dependency properties for command and commandparameter. Setting all controls to have the same group Id. Data template to override display of radio button to make it look like a visual button with triggers for mouseover and isselected.
This works fine, except for one thing. Once you select a radio button in a group, there is no way to deselect all options in the radio button group. So if you navigate to "maintenance" and then click the sub menu for "Countries" for example, then you are displayed the country maintenance screen. If you then go to a different area of the app and select "Deal Entry" from the main menu, you are taken to the deal entry screen. If you then click "Maintenance", it displays the generic "maintenance" content and brings back the sub menu control for maintenance, where "Country" is selected in the radio button group, but this is undesirable. When you navigate back to Maintenance, it should deselect all sub menu options, display the generic maintenance landing page content and let you select a sub menu option before displaying that screens content. The first time you load Maintenance, nothing is selected, but once you have chosen an option, then there is no way to have nothing selected again when you reload the maintenance screen.
2) I then tried extending a ListBox, styling it with a horizontal stackpanel for the content, each listboxitem is a menubuttonViewModel. This allows me to only select a single option at a time and to clear the selection when you navigate away from the page. It also lets me change the background when you mouse over each listboxitem.
The bit I can't get working with the listbox is to have the background different on the IsSelected trigger. There seems to be some trigger on the default ListBoxItem template that overrides anything you specify in CSS so no matter what trigger I put on the listboxitem or menubuttonviewmodel style, the background simply does not change. I think I need to redefine the data and content template for listboxitem, but only have it apply for this listbox, so it can't be a global template change to all listboxitems - as I want to be able to use listboxes elsewhere in the app without inheriting this behaviour.
Can anyone give their thoughts on these two approaches and how to perhaps solve the issues I'm having to make one of them work in the way I want, particularly if you can advise how I can override the content/data template for the listboxitems in my style so they do not use the default triggers, and I can get the IsSelected trigger working for me?
If I understood correctly, you would want to clear the selection on the RadioButtons from the Sub-Menu each time you navigate back from another Main Menu option.
In order to solve this, you could have every Radio Button "unchecked" by manually setting the RadioButton´s IsChecked property value to false. A possible solution could be the following:
If you want to clear any checked option from the Sub-Menu everytime you navigate to a different section of the Main Menu, you could first notify to the Sub-Menu´s ViewModel by publishing an event using the EventAggregator after selecting and clicking a different MainMenu button, from the SelectionChangedEventHandler method of the Main Menu´s ViewModel.
Therefore, the Sub-Menu EventHandler of the published event would update each RadioButton´s IsChecked property value to false, which it could be accomplished by using a "Two-Way" Binding between each IsChecked property defined on the View, and each boolean "RadioButton1IsChecked" property implemented on the ViewModel.
I hope this helped you.
I am working on a WPF PRISM application that has the following structure (I have simplified to explain better without additional layers). I am using Unity as my DI/IOC
AppMain - Bootstrapper
Gui - Views and View Models
Data - Data using EF.
In Gui, I have views names as below:
Home
EmployeesView
OrdersView
Reports
I have three regions in the shell.
MainRegion - Main Content
TopRegion - Navigation Menu
BottomRegion - Status Bar
I am using the following method to register views to the regions
IRegion region = _regionManger.Regions[RegionNames.MainRegion];
var mainView = _container.Resolve<Home>();
region.Add(mainView, ViewNames.HomeViewName);
region.Activate(mainView);
The first of activation happens in the Module Initialize method for Top, Main and Bottom.
After this, I am activating other views when the button are clicked. It is just code behind for now. Sample code here:
IRegion region = _regionManger.Regions[RegionNames.MainRegion];
var reportView = region.GetView(ViewNames.ReportsViewName);
if (reportView == null)
{
reportView = _container.Resolve<ReportsView>();
region.Add(reportView, ViewNames.ReportsViewName);
region.Activate(reportView);
}
else
{
region.RequestNavigate(ViewNames.ReportsViewName);
}
PROBLEM1: Any advise on how this can be done or the way I am doing is fine.
The top menu has Home, Employees, Orders, Reports buttons.
In the home page I have recent orders by the employee in datagrid as readonly.
I would like to double click to navigate to the OrderView and pass the selected order to show to the user. PROBLEM2 I am not sure where to do the navigation for this.
PROBLEM3: Another issue was if set the RegionMemberLifeTime keepAlive false, INavigationAware methods don't fire. If I don't set the KeepAlive to false, the page does not get refreshed because, the view model does not get called.
I need the pages to refresh when it is navigated to and not be stale and also handle any confirm prompts to the user when the view is navigated away from it.
Your help is very much appreciated.
it's certainly too late but…
Problem 1/2: is there a particular reason why you add content to region in module initializer?
the common way is more like -> in xaml:
<ContentControl prism:RegionManager.RegionName="MainRegion" />
and in ModuleInit.cs -> Initialize()
_regionManager.RegisterViewWithRegion("MainRegion", () => _container.Resolve<MainView>());
Problem 3:
the view has to implements INavigationAware, IRegionMemberLifetime
and to swich region, in the viewModel you do:
_regionManager.RequestNavigate("RegionWhatever", new Uri("TestView", UriKind.Relative));
But to work you have to register it in ModulInit.cs as an object with viewName, like that:
_container.RegisterType<Object, TestView>("TestView");
and a contentControl with the correct RegionName define in xaml of course
Like the title said,how may i turn the grid(or page) and the components in it into background gray and unable and show a new component in foreground.
It's a common effect in the web page,but i cannot do that with a xaml.
Please answer in detail better with sample code if you do.Thanks in advance.
Here's an example of using a Popup to display a UserControl when a Page is navigated to. The OnNavigatedTo function creates a popup, binds a Click event to the UserControl, and then shows the UserControl over the entire page. If the correct password is entered, ("password" in the example) the control disappears. You'll need to modify it for your own requirements, but it should definitely get you started.
https://skydrive.live.com/redir.aspx?cid=ef08824b672fb5d8&resid=EF08824B672FB5D8!343
You'll want to use the VisualStateManager and create some animation transitions to switch between the old and new components. I won't paste the code here for brevity, but if you check out:
http://visualstudiomagazine.com/articles/2011/07/22/wcmob_visual-states.aspx
You'll see a simple example of switching between two UI components on a single page within a Windows Phone 7 PhoneApplicationPage. In your scenario, you'd use this paradigm to create 2 animation storyboards, one for showing an overlay control and one for settings the 'disabled' property on the main grid.
In my MainWindow.xaml, I have a DockPanel that contains Menu, Page and Status Bar. I want to show this Page when an option is clicked from the Menu. The Page should appear as centered to the parent, MainWindow. This Page will be acting as a center place to show different Forms, i.e, User Controls, Content etc..
I am not following how to add a reference in the Code-Behind .cs file of the MainWindow to show this Page.
For most things that I want to Disappear/Reappear, I set the visibililty. If you are using the codebehind for this, ensure that the page has a name:
<Page x:Name="MyPage"/>
Then you should be able to do something like:
This.MyPage.Visibility = Visibility.Collapsed;
Unless your page is a resource, If that is the case, just:
This.FindResouce("MyPage");
Out of curiosity, why do you want to use a page? I have never had cause to use one and would like to know what one needs it for.
I need to have button have 4 images that are changed by the application action.
I want to define new class ButtonEx that inherit from the Button class.
So, i did it by adding 'silverlight template control' and it to be inherit from control to Button.
Now, i cant see the images whan i put this ButtonEx on the page.
What i did wrong ?
How to fix it ?
( same code work fine in WPF )
Can you post any of your code? Did you create a visual style for it in themes\generic.xaml? Did you set the default style key?
I recently followed this tutuorial for a TextBox, you could so something similar for your button... http://www.silverlightshow.net/items/Create-a-Custom-Control-Inheriting-from-TextBox.aspx
Store your images as resources then create a user control that has
- a button and the content of the button is an image
- a property to select the image from the resources
use the usercontrol as your button.
please post a code sample...
to inherit form button you simply need this.
public class ButtonEx:Button
{
}
this will have all functionality that button has.
if you want new template just add it in Themes/generic.xaml
From your question its not clear that you really need to be subclassing Button. Maybe you can get by with just copying and modifying the template of button (Blend helps for this), or just have the image as content bound to some property for the application to change (using a ValueConverter perhaps).