I'm currently creating a WPF application, using C# and XAML in Visual Studios 2010.
I have a master grid. In that master grid I have a group bar which you can select different items. Depending on what you select, the middle of the master grid can be totally different. What I was wondering is, what's the best way to program the middle part?
Right now, I have it set up in such a way that everything in the middle is dynamically programed in C#, and everything on the outside is programmed in XAML.
In C# I programmed: for each group bar item, there is a grid that goes with it (so that different content can be displayed on it). Each grid is a child of the master grid. Each grid is visible or hidden when necessary. Is this the best way to approach this?
The best example of this is in Outlook 2007, where you have your group bar on the right hand side. When you select different items on the group bar (mail, calendar, tasks) the right of the group bar completely changes.
The easy way to do this in WPF is to define DataTemplates for each of your "middle" sections.
Using the Outlook example, you might have a MessageCollection class that stores a list of messages, an EventCollection class that stores a list of calendar events, and a TaskCollection class that stores a list of tasks.
In your "middle" area you would simply have a single ContentPresenter whose Content would be set to a MessageCollection, EventCollection, or TaskCollection. Presumably this would be done using a binding to a view model property.
Here is how it might look:
<Window ...>
<Grid>
<!-- group bar area -->
...
<!-- "middle" area -->
<ContentPresenter Grid.Row="1" Grid.Column="1"
Content="{Binding SelectedCollection}" />
</Grid>
</Window>
Now you create a DataTemplate for each of the collection types, for example:
<DataTemplate TargetType="{x:Type my:MessageCollection}">
<Grid>
... put the XAML for displaying mailbox contents here ...
</Grid>
</DataTemplate>
<DataTemplate TargetType="{x:Type my:EventsCollection}">
<Grid>
... put the XAML for displaying a calendar here ...
</Grid>
</DataTemplate>
<DataTemplate TargetType="{x:Type my:TasksCollection}">
<Grid>
... put the XAML for displaying a to-do list here ...
</Grid>
</DataTemplate>
With this setup, all you have to do to switch the inner grid is to set your "SelectedCollection" property in your view model to a different collection type.
Related
i am almost new to C# with WPF. I have a small problem. Maybe the solution is very easy, but i don't see it right now. So i want to make different TABLES. I use Grids to make my own table. Now i want to switch between the tables at different states of my application, so that i make a grid invisible and the one i need visible. How do i implement several grid tables in XAML? For example i have a tabcontrol and in the tabitem i want to place more than one grids, but thats not possible. I tried using StackPanel for example but then i have a gap at the bottom of the grid. I need a way to define several grids and switch between them. Before C# i worked with MATLAB and i just put every table in a PANEL and switched them visible and invisible when i needed them. Is there no similar way in WPF?
Greetings
In such cases, i would go with UserControls. One usercontrol for each grid type. A sample (not related to Grid in question) would be like the below.
<Window.Resources>
<ResourceDictionary>
<DataTemplate x:Key="DTGlobalAdminManager">
<AC:UCGlobalAdmin DataContext="{Binding Source={x:Static GVM:VMAdminConsole.Instance}, Path=ViewModelGlobalAdmin}"/>
</DataTemplate>
<DataTemplate x:Key="DTCompanyAdminProjects">
<AC:UCCompanyAdmin DataContext="{Binding Source={x:Static GVM:VMAdminConsole.Instance}, Path=ViewModelCompanyAdmin}" />
</DataTemplate>
<DataTemplate x:Key="DTProjectAdminManager">
<AC:UCProjectAdminManage DataContext="{Binding Source={x:Static GVM:VMAdminConsole.Instance}, Path=ViewModelProjectAdmin}"/>
</DataTemplate>
<DataTemplate x:Key="DTGlobalAdminAssignCategories">
<AC:UCGlobalAdminCategories DataContext="{Binding Source={x:Static GVM:VMAdminConsole.Instance}, Path=ViewModelGlobalAdmin}"/>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
You can set up a content control and different usercontrols (each containing different grid template). Then switch them using a Style Trigger.
For school I have to create a boardgame of my choice. I chose a simple boardgame where you have to combine blocks of different colors in a way to gain most points out of it. You can have 2 to 4 players.
Until now I build a WPF application with MVVM and PRISM. The user is pressing a button to decide the amount of players and based on that I want to create a grid dynamically in XAML (because of MVVM and no code-behind) with sizes of 6x6, 7x7 and 8x8. In each cell there need to be a control (I don't know which one) which can hold a visual block.
My idea is to create that grid, put a ListBox in each cell, allow just one item for the ListBox and drag and drop a Rectangle on it.
For the dynamically created grid I read about using ItemsControl to build it up. Here a short code example, which isn't working:
<ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding Path=GameBoard}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ShowGridLines="True" Row="{Binding Path=Rows}" Column="{Binding Path=Columns}">
<Grid.RowDefinitions>
<RowDefinition MinHeight="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="20"/>
</Grid.ColumnDefinitions>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Inside I could place a ListBox to hold that block I was talking about. For my understanding I need to have a property bound to every single cell/ListBox to actually hold it and work with it in code.
There is plenty of stuff on the internet, but I couldn't wire it together to get it working. Do you have a point to start for me?
I have a list (ListBox) of items in XAML using a StackPanel- based element template. The layout is fine, but I would now like to have a rectangle as a background for each item - creating a box around each one.
I was thinking of using a Canvas somehow, but as each item's height varies (as well as the height of the items inside the StackPanel), I'm not sure how to do it (I'm new to C#/XAML). What would be the best composition for the template in this situation?
You can just specify it in an ItemTemplate and it will do what you want, something like;
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderBrush="Red" BorderThickness="2" Background="Blue"/>
<!-- Insert the rest of your Item template stuff here -->
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
ListBox is a type of ItemsControl, which exposes several properties to control the appearance of the items. In this case, have a look at ItemContainerStyle (in the case of ListBox, the item containers are instances of ListBoxItem). You could, for instance, set the Background property in an ItemsContainerStyle to some color.
I have a WPF window displaying different self-defined Views. So far I was able to use everything I learned about MVVM :)
Now I got to a new "problem": I have 10 entities of the same view in a bigger view. These ten view-entities contain a set of controls (textbox, combobox etc.) but are all consistent.
So how do I bind these Views to a ViewModel?
I thought about having 10 instances of the ViewModel in the "higher-level" ViewModel and give the views fix-defined the instances of the VM as datacontext.
My question is now --> Is there a easier (or more convienient) way to bind many (identical) views to their viewmodels?
Code-Example:
View Model:
private PanelViewModel _panelViewModel1 = new PanelViewModel();
public PanelViewModel PanelVM1
{
get { return _panelViewModel1; }
}
View-Example:
<myControls:vwPanel HorizontalAlignment="Left" x:Name="vwPanel1"
VerticalAlignment="Top" DataContext="{Binding Path=PanelVM1}"/>
What bothers me is that I would need this logic ten times for ten views?
UPDATE:
To answer some questions: I want to show one view 10 times (in my example) I defined my own view by inheriting from UserControl. So my vwPanel inherits from UserControl. The 10 vwPanels are just placed inside a StackPanel inside a Grid.
It's not about displaying data, as you pointed out, there would be a listview or a datagrid a better place to start. It's a special case where I need this much input-controls :/
UPDATE2: What I hoped for was more like defining a List of ViewModels and Bind my 10 Views to one of this List. But this will not work will it? At least I wouldn't know how to refernce one "special" entitiy in the list out of XAML...
Typically I use implicit DataTemplates for mapping Views to ViewModels. They can go in <Application.Resources>, <Window.Resources> or even in under specific elements only such as <TabControl.Resources>
<DataTemplate DataType="{x:Type local:PanelViewModel}">
<myControls:vwPanel />
</DataTemplate>
This means that anytime WPF encounters an object in the VisualTree of type PanelViewModel, it will draw it using vwPanel
Objects typically get placed in the VisualTree through an ItemsSource property
<ItemsControl ItemsSource="{Binding CollectionOfAllPanels}" />
or by using a ContentControl
<ContentControl Content="{Binding PanelVM1}" />
If I understand your question correctly, you have a collection of something that you what to represent visually. That is, you have several viewmodels that you want to define a single view for, but show X number of times. Your example shows you using a panel as your view for the "PanelViewModel"...what is the parent item's control for the vwPanel? Assuming you're using something like a ListBox, you can define a custom DataTemplate that contains your vwPanel and assign that DataTemplate to your ListBox.ItemTemplate.
For example:
<Window.Resources>
<DataTemplate x:Key="myVMTemplate" TargetType="{x:Type myViewModels:PanelViewModel}">
<myControls:vwPanel HorizontalAlignment="Left" VerticalAlignment="Top"/>
</DataTemplate>
</Window.Resources>
<ListBox ItemsSource="{Binding Path=MyCollectionOfPanelVMs}"
ItemTemplate="{StaticResource myVMTemplate}" />
I haven't verified that this works.
I have 3 user controls in WPF which have the same layout (a few buttons and a listview) but the code in behind is different because the listviews list collections of different classes.
Is it possible to somehow use the same XAML for the three usercontrols? Because right now, if I make a change to the layout of one XAML I have to do it for the other two manually.
Thanks
That's perfect scenario for MVVM
Create a single UserControl or View
Create three different backend classes which will act as ViewModel
For each instance of UserControl use different ViewModel as DataContext
1) Extract common XAML into the separate XAML file and then in target control's use it as DataTemplate:
<!-- 1. CommonView.xaml would contains common XAML -->
<!-- 2. Below is XAML of the any of three control -->
<UserControl>
<!-- In three controls use shared XAML as data template -->
<UserControl.Resources>
<DataTemplate x:Key="sharedTemplate">
<views:CommonView />
</DataTemplate>
</UserControl.Resources>
<MyControl>
<ContentPresenter ContentTemplate="{StaticResource sharedTemplate}" />
</MyControl>
</UserControl>
2) Bind each of the control to a separate ViewModel