WPF: Similar xaml - wpf

So i have some similar windows and their xamls are the same. Obviously duplicated code is not good. And i would like my windows shared xaml from only file. I created DataTepmlate containing common xaml and placed it into ResourceDictionary. But i don't know how to place DataTemplate from resource dictionary into xaml file.
my datatemplate:
<UserControl x:Class="PeriodicTable.View.CollectionViews.CollectionTemplate"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ListBox Name="Lst" ItemsSource="{Binding Entity}"
HorizontalContentAlignment="Stretch"
Grid.IsSharedSizeScope="True" >
<!-- lots and lots of code -->
</ListBox>
</Grid>
</UserControl>
my Resources.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:collectionViews="clr-namespace:PeriodicTable.View.CollectionViews"
xmlns:collectionViewModels="clr-namespace:PeriodicTable.ViewModel.ViewModel.CollectionViewModels">
<DataTemplate x:Key="ComonCollectionTemplate" DataType="{x:Type collectionViewModels:PeriodsCollectionViewModel}" >
<collectionViews:CollectionTemplate />
</DataTemplate>
</ResourceDictionary>
File where i would like to put my datatemplate:
<Window x:Class="PeriodicTable.View.CollectionViews.PeriodCollectionWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PeriodWindow" Height="350" Width="750" >
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
what i should write here to place my DataTemplate from Resources.xaml?
</Window>

Use ContentControl and set its ContentTemplate to the resource declared in resource file.
<ContentControl ContentTemplate="{StaticResource ComonCollectionTemplate}"/>

Related

ViewModel location into sub-folder (XAML, namespace)

Into MainWindow.xaml I have:
<Window x:Class="LayoutMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
ResizeMode="NoResize"
xmlns:local="clr-namespace:LayoutMVVM"
xmlns:veiwmodels="clr-namespace:LayoutMVVM.ViewModels"
xmlns:views="clr-namespace:LayoutMVVM.Views"
Title="Layout" Height="750" Width="650">
Into Windows.Resources I'm binding dataContext:
<Window.Resources>
<DataTemplate x:Name="SettingsTemp" DataType="{x:Type veiwmodels:SettingsModel}">
<views:SettingsView DataContext="{Binding}" />
</DataTemplate>
</Window.Resources>
But when my other model and view is located into sub-folder as below:
I can't do:
<DataTemplate x:Name="OpenTemp" DataType="{x:Type ViewModels:Open.OpenModel}">
<views:Open.OpenView DataContext="{Binding}" />
</DataTemplate>
or LayoutMVVM.ViewModels.Open.OpenModel
or LayoutMVVM/ViewModels/Open/OpenModel
You should add new one in header of control:
xmlns:veiwmodelsOpen="clr-namespace:LayoutMVVM.ViewModels.Open
or you can set namespace of OpenModel to LayoutMVVM.ViewModels (not LayoutMVVM.ViewModels.Open).
There is no other way, I think.

wpf window start up images

I would ideally like to keep the resources for a window in a resource dictionary, but am getting stuck as to the best way to make them known before you declare the window.resources section. So I wind up doing something like the code below.
Is there someway to reference the background image brush statically? How can I do better?
Cheers,
Berryl
<Window x:Class="Smack.ConstructionAdmin.Presentation.Wpf.Views.ProjectPicker.ProjectPickerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
Background="{DynamicResource waveBrush}"
Icon="pack://application:,,,/MyAssembly;component/Images/Project_32.png"
...
>
<Window.Resources>
<ImageBrush
x:Key="waveBrush" Stretch="Fill" ImageSource="pack://application:,,,/MyAssembly;component\Images\Wave.jpg"
/>
</Window.Resources>
In your projects Application.xaml file in the Application.Resources Section.
Your could also use a standalone Resource File and include it in your windows xaml file or the Application.xaml file.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Background="{DynamicResource MyBackColor}">
<Window.Resources>
<ResourceDictionary Source="Resources\MyResourceDictionary.xaml" />
</Window.Resources>
<Grid>
</Grid>
</Window>
Or
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary Source="Resources\MyResourceDictionary.xaml" />
</Application.Resources>

How can I display my user control in the MainWindow?

I'm trying to build a small MVVM test application, but can't really figure how to display my user control in the MainWindow.
My Solution Explorer:
I got a resource dictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MVVM.ViewModel"
xmlns:vw="clr-namespace:MVVM.View">
<DataTemplate DataType="{x:Type vm:ViewModel}">
<vw:View />
</DataTemplate>
</ResourceDictionary>
I got my view:
<UserControl x:Class="MVVM.View.View"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="PersonTemplate">
<StackPanel>
<TextBlock Text="{Binding FirstName}" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<ListBox ItemsSource="{Binding Path=Persons}"
ItemTemplate="{StaticResource PersonTemplate}" />
</UserControl>
and My MainWindow
<Window x:Class="MVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:MVVM.ViewModel"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary Source="MainWindowResources.xaml" />
</Window.Resources>
<Grid>
</Grid>
</Window>
The most obvious and easiest way is to add the ContentControl element:
<Grid>
<ContentControl x:Name="mainContentControl" />
</Grid>
And after that set the Content property of this control to your view model, and the corresponding view will be loaded and applied automatically:
this.mainContentControl.Content = new ViewModel.ViewModel();
But I would prefer to use another way without datatemplates:
<Grid>
<vw:View x:Name="mainView"/>
</Grid>
this.mainView.DataContext = new ViewModel.ViewModel();
Build your VS2010 solution, then, go to your MainWindow's XAML.
On the left, there is a toolbar with button "Toolbox"
Open it, it contains all the possible WPF controls you could add to your UI
Your UserControl should appear on top of the list (in a category probably named "MVVM Controls"), just drag&drop it to your UI :)

Set Style for user control

I am trying to set a style for my user control. The UserControl is in a project "Controls" and the theme is in a project "MainProject"
<UserControl x:Class="Controls.OutputPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
x:Name="OutputControl">
<!-- Style="{DynamicResource UserControlStyle}"> - I cant set the style here because the Resource Dictionary hasn't been defined yet -->
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MainProject;component/Themes/MyTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- Now that the Resource Dictionary has been defined I need to set the style -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="textbox"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Text="{Binding ElementName=OutputControl, Path=TextProperty}"
IsReadOnly="True"
Style="{DynamicResource OutputTextBoxStyle}"/>
</Grid>
</UserControl>
That should be working fine as far as I can see. Do you get any special warnings or errors or do some parts from the Style not get applied?
To set the Style after Resources has been set, you can use the following syntax
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MainProject;component/Themes/MyTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.Style>
<DynamicResource ResourceKey="UserControlStyle"/>
</UserControl.Style>
If you're still having problems after this you can compare it to my sample app which I uploaded here: http://www.mediafire.com/?q1v98huubzw02zb
You could make new resource dictionary, define your style there and than add it in app resources.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UC="clr-namespace:UserControls;assembly=UserControls">
<Grid>
<UC:myUserControl/>
</Grid>
</Window>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UC="clr-namespace:UserControls;assembly=UserControls">
<Style TargetType="UC:myUserControl">
...
</Style>
</ResourceDictionary>
And

Referencing a Parent's ResourceDictionary in a UserControl

I have a library of WPF UserControls, and a ResourceDictionary that is shared within the library.
All the UserControls in this library appear only within a single 'shell' parent control, which is really just a container for a collection of smaller controls. I'm able to access the ResourceDictionary from my shell control as expected when I add the following XAML
<Control.Resources>
<ResourceDictionary Source="MyResources.xaml" />
</Control.Resources>
However I can't access the ResourceDictionary from child controls that sit inside the 'shell' control.
I was under the impression that WPF should check locally for resources, and then traverse upwards until appropriate resources are found?
Instead I'm getting
Cannot find resource named '{BoolInverterConverter}'.
Resource names are case sensitive. Error at
object 'System.Windows.Data.Binding' in markup file...
Obviously I can (and am) referencing the ResourceDictionary in my child controls; but each and every control now needs to reference this dictionary and I believed that this was not necessary.
Any ideas, am I doing something strange or is my expectation of behaviour incorrect?
What's going on is described here, though the documentation's a little opaque. If you add a ResourceDictionary to an element'sResources property without specifying a key, WPF expects that you're merging in resource dictionaries, and it populates the dictionary with the contents of the dictionaries in its MergedDictionaries property. It ignores the actual contents of the ResourceDictionary with no key.
So what you want to do is this:
<Control.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MyResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Control.Resources>
Edit:
A working example:
MainWindow.xaml:
<Window x:Class="MergedDictionariesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:MergedDictionariesDemo="clr-namespace:MergedDictionariesDemo" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<MergedDictionariesDemo:UserControl1 />
</Grid>
</Window>
Dictionary1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="UCBrush"
Color="Bisque" />
</ResourceDictionary>
UserControl1.xaml:
<UserControl x:Class="MergedDictionariesDemo.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Border Margin="10" BorderBrush="Navy" BorderThickness="1" CornerRadius="10">
<TextBlock Margin="10"
Background="{DynamicResource UCBrush}">
The background of this is set by the resource UCBrush.
</TextBlock>
</Border>
</UserControl>

Resources