Load resources located in seperate files inside the MainWindow.xaml - c#

Goal: Creating an XAML template which I can reuse and load into my main view. Is this possible? If so how? Ive read about the ResourceDictionary and came up with something but im not sure where to continue from there.
This is the XAML with my resource (kept very dumb and simple):
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel x:Key="myUnneccesaryButtonList">
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
</ResourceDictionary>
Here my MainWindow XAML where I want to use the above template and load it:
<Window x:Class="Sample.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"
Title="Sample" WindowState="Maximized">
<StackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</StackPanel>
</Window>
Edit: Here is my MainWindow but the Window.Resource declaration doesnt work:
<Window x:Class="Sample.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"
Title="Sample" WindowState="Maximized">
<Window.Resources>
<ResourceDictionary Source="MyDictionary.xaml" >
</Window.Resources>
<StackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</StackPanel>
</Window>

myUnneccesaryButtonList is not a template but an actual StackPanel instance.
If you set its x:Shared attribute to false in the ResourceDictionary:
<StackPanel x:Key="myUnneccesaryButtonList" x:Shared="False">
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
..you could use a ContentControl to display it in the window:
<ContentControl Content="{StaticResource myUnneccesaryButtonList}" />
What you probably want to do is to create a custom StackPanel class that always adds the Buttons though:
public class CustomStackPanel : System.Windows.Controls.StackPanel
{
public CustomStackPanel()
{
Children.Add(new Button() { Content = "1" });
Children.Add(new Button() { Content = "2" });
Children.Add(new Button() { Content = "3" });
}
}
Usage:
<local:CustomStackPanel x:Name="wrapper" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>

if you want a XML Template then you should create a template
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="myUnneccesaryButtonList">
<StackPanel >
<Button Content="1"></Button>
<Button Content="2"></Button>
<Button Content="3"></Button>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
then you could define a control to host it
<ContentControl ContentTemplate="{StaticResource myUnneccesaryButtonList}" />
or
<ItemsControl ItemTemplate="{StaticResource myUnneccesaryButtonList}" />
Remember add the dictionary into the Resources
<Window.Resources>
<ResourceDictionary Source="YourDictionary.xaml" />
</Window.Resources>
or to merge it in
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="YourDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

Related

WPF Custom Fonts is not showing on the Design Window

I'm working on a WPF application using C#. So far, I have added a custom font using a ResourceDictionary on my application. When I run the app I can see the font works fine, but on the Design tab of my XAML it always shows the default font. Could I be missing something to set my designer correctly?
App.xaml
<Application x:Class="Bali.Chat.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Bali.Chat"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/Fonts.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Fonts.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="LatoRegular">pack://application;,,,/Fonts/#Lato Regular</FontFamily>
<FontFamily x:Key="LatoThin">pack://application;,,,/Fonts/#Lato Thin</FontFamily>
</ResourceDictionary>
MainWindow.xaml
<Window x:Class="Bali.Chat.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"
xmlns:local="clr-namespace:Bali.Chat"
mc:Ignorable="d"
Icon="Images/Logo/logo-small.png"
WindowStyle="None"
AllowsTransparency="True"
Title="Bali Chat"
Height="250" Width="400">
<StackPanel>
<TextBlock Text="Default Font!" FontSize="40" />
<TextBlock Text="Thin Font" FontSize="40" FontFamily="{StaticResource LatoThin}" />
<TextBlock Text="Regular Font" FontSize="40" FontFamily="{StaticResource LatoRegular}" />
</StackPanel>
</Window>
This is what I get on my designer
And this is what I get if I run the application
I really would like to preview what I'm trying to render without having to start the application or check it on the live preview. The tutorial I am following does show the presenter seeing the proper font in the designer, so I know there are some issues. Thanks in advance.

DataTemplate doesn't properly bind the properties as specified

I have the following DataTemplate in DataTemplates.xaml
<DataTemplate DataType="{x:Type local:ExcelReportVM}">
<local:ExcelReport DoubleClickHandler="{Binding}">
<local:ExcelReport.RowColorConverter>
<local:ReportRowColorConverter/>
</local:ExcelReport.RowColorConverter>
</local:ExcelReport>
</DataTemplate>
I make sure that this DataTemplate is usable within the application scope via the following App.xaml definition:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DataTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And this is my control ExcelReport.xaml:
<UserControl x:Class="WpfApplication1.ExcelReport"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
....
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="HeaderTemplate">
<TextBlock TextAlignment="Center" Text="{Binding .}" TextWrapping="WrapWithOverflow" />
</DataTemplate>
</UserControl.Resources>
<UserControl.DataContext>
<local:ExcelReportVM/>
</UserControl.DataContext>
<syncfusion:SfDataGrid ItemsSource="{Binding Entries}" x:Name="grid" Background="White"
HeaderTemplate="{StaticResource HeaderTemplate}"
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=UserControl}}">
</syncfusion:SfDataGrid>
</UserControl>
My code behind: ExcelReport.xaml.cs
public partial class ExcelReport : UserControl
{
public static readonly DependencyProperty RowColorConverterProperty = DependencyProperty.Register(
"RowColorConverter",
typeof(IValueConverter),
typeof(ExcelReport),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnRowColorConverterChanged))
);
public IValueConverter RowColorConverter
{
get { return (IValueConverter)GetValue(RowColorConverterProperty); }
set { SetValue(RowColorConverterProperty, value); }
}
public ExcelReport()
{
InitializeComponent();
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
Debug.Assert(DataContext.GetType()==typeof(ExcelReportVM)); //DataContext is correct
Debug.Assert(RowColorConverter!=null); //but this is null
}
}
I've no idea why I can successfully bind the DataContext, but the <DataTemplate DataType="{x:Type local:ExcelReportVM}"> that I define is not used, I thought everything inside the DataTemplates.xaml is accessible to ExcelReport.xaml?
Note: There is no error in the output window, and there is no exception been thrown anywhere in the code.
If it is a ContentControl, then you have to set its Content as <ContentControl Content="{Binding SomeProperty}"/> , then based on DataType of SomeProperty correct DataTemplate is picked up.
This is how I fix the problem, I don't set the UserControl.DataContext to ExcelReportVM at ExcelReport.xaml; instead, I set the ContentControl.Content to ExcelReportVM at MainWindow.xaml.
Updated code at ExcelReport.xaml:
<UserControl x:Class="WpfApplication1.ExcelReport"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
....
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<DataTemplate x:Key="HeaderTemplate">
<TextBlock TextAlignment="Center" Text="{Binding .}" TextWrapping="WrapWithOverflow" />
</DataTemplate>
</UserControl.Resources>
<!-- <UserControl.DataContext> this is not longer needed
<local:ExcelReportVM/>
</UserControl.DataContext> -->
<syncfusion:SfDataGrid ItemsSource="{Binding Entries}" x:Name="grid" Background="White"
HeaderTemplate="{StaticResource HeaderTemplate}"
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=UserControl}}">
</syncfusion:SfDataGrid>
</UserControl>
Code at MainWindow.xaml
<Syncfusion:RibbonWindow x:Class="WpfApplication1.MainWindow"
...
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized"
Syncfusion:SkinStorage.VisualStyle="Office2013"
xmlns:Syncfusion="http://schemas.syncfusion.com/wpf">
<Grid x:Name="ExcelReport22">
<ContentControl> <!-- this is where the ExcelReportVM is binded to -->
<local:ExcelReportVM/>
</ContentControl>
</Grid>
</Syncfusion:RibbonWindow>

Creating a Custom ScrollViewer using WPF UserControl

I'm trying to create a ScrollViewer with some customizations. Like this:
UserControl1.xaml:
<UserControl x:Class="MyApp.Control.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="100" d:DesignWidth="300">
<UserControl.Template>
<ControlTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<ContentPresenter Grid.Row="0" Content="{Binding ElementName=uc, Path=DynamicUserControl}" />
<Rectangle Grid.Row="1" Fill="#88ff0000" />
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
UserControl1.xaml.cs:
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public static readonly DependencyProperty DynamicUserControlProperty = DependencyProperty.Register("DynamicUserControl", typeof(object), typeof(UserControl1), new PropertyMetadata(null));
public object DynamicUserControl
{
get { return GetValue(DynamicUserControlProperty); }
set { SetValue(DynamicUserControlProperty, value); }
}
}
TestForm.xaml (Using the UserControl1):
<Window x:Class="MyApp.TestForm"
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"
xmlns:local="clr-namespace:MyApp.Control"
mc:Ignorable="d"
Title="TestForm" Height="200" Width="500">
<Grid Background="{StaticResource AimDarkGradBg01}">
<local:UserControl1>
<local:UserControl1.DynamicUserControl>
<Button>Click me</Button>
</local:UserControl1.DynamicUserControl>
</local:UserControl1>
</Grid>
</Window>
But the problem is no matter what content I put in the local:UserControl1.DynamicUserControl, nothing is rendered.
Anyone can help me?
The problem is actually you binding expression. The correct binding should be like:
UserControl1.xaml:
<UserControl x:Class="MyControls.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"
xmlns:local="clr-namespace:MyControls"
mc:Ignorable="d"
x:Name="uc">
<Grid>
<ScrollViewer>
<WrapPanel>
<!-- Dynamic Content -->
<ContentPresenter Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type control:UserControl1}}, Path=DynamicUserControl}"/>
</WrapPanel>
</ScrollViewer>
<Canvas>
<!-- Some Code -->
</Canvas>
</Grid>
</UserControl>
If you noticed I removed your definition of the template, in which case you don't need it. You can simply just put your code inside the user control.
The other files are correct. Fix what I told you above and you're good to go.

WPF Navigate from frame in window to Usercontrol and pass parameters to it

I have a modern window in WPF/C# application, in which I added a modern frame:
<mui:ModernWindow x:Class="MyApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
WindowStartupLocation="CenterScreen"
Style="{StaticResource EmptyWindow}">
<Window.Resources>
</Window.Resources>
<Grid>
<Menu x:Name="menu" Height="62" VerticalAlignment="Top" >
<MenuItem x:Name="miHome" Header="Home" Click="MenuItem_Home" IsChecked="True" Width="60" FontSize="14" />
<MenuItem x:Name="miClients" Header="Clients" FontSize="14" Click="MenuItem_Clients" Width="65"/>
<MenuItem x:Name="miSuppliers" Header="Suppliers" FontSize="14" Click="MenuItem_Suppliers" Width="81"/>
<MenuItem x:Name="miReports" Header="Reports" FontSize="14" Click="MenuItem_Reporting" Width="71"/>
</Menu>
<mui:ModernFrame Margin="0,75,10,10" x:Name="frame">
</mui:ModernFrame>
</Grid>
I have MenuItems in my application, when I click on Suppliers item, I fill the frame with a usercontrol, like this:
frame.Source = new Uri("/Pages/Suppliers.xaml", UriKind.Relative);
Where Suppliers.xaml design is:
<UserControl
x:Class="MyApp.LinksBar.Suppliers"
xmlns:MyApp="clr-namespace:MyApp"
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"
xmlns:mui="http://firstfloorsoftware.com/ModernUI"
mc:Ignorable="d"
d:DesignHeight="575" d:DesignWidth="905">
<UserControl.Resources>
</UserControl.Resources>
<Grid Name="Grid">
<mui:ModernButton x:Name="btnmakePayment" Content="Make Payment" Click="btnMakePayment_Click" Grid.Row="2" HorizontalAlignment="Right" VerticalAlignment="Top"/>
</Grid>
</UserControl>
When I click on "Make Payment" button, I navigate to another UserControl (MakePayment.xaml):
private void btnMakePayment_Click(object sender, RoutedEventArgs e)
{
NavigationCommands.GoToPage.Execute(new Uri("/Actions/MakePayment.xaml", UriKind.Relative), this);
}
MakePayment.xaml design is:
<UserControl
xmlns:local="clr-namespace:MyApp.Actions" x:Class="MyApp.Actions.MakePayment"
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"
xmlns:mui="http://firstfloorsoftware.com/ModernUI" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:MyApp="clr-namespace:MyApp"
mc:Ignorable="d"
Loaded="MakePayment_Loaded"
d:DesignHeight="600" d:DesignWidth="866" >
<UserControl.Resources>
</UserControl.Resources>
<Grid DataContext="{StaticResource makePaymentViewSource}" Name="Grid">
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<Label Content="Total" VerticalContentAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Top"/>
// More design code here ...
</Grid>
</UserControl>
Here comes my question:
I need to pass parameters from Suppliers UserControl to MakePayment UserControl.
How to programmatically pass the parameters in Suppliers and read them in MakePayment?
Thank you.
If you can bind one to the other, that is what you should be doing. By far, the easiest way to make two UserControls "communicate" (or share properties that both can do stuff with) is to define a DependencyProperty on each and bind them two-way.
This way, both always have access to the same value and both can do stuff with it.
Take my own control as an example:
<UserControl x:Class="MyControls.MasterContainerControl"
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"
xmlns:local="clr-namespace:MyControls"
mc:Ignorable="d"
x:Name="masterContainerControl">
<local:ContainerControl SomeProperty="{Binding ElementName=masterContainerControl, Path=SomeProperty}">
<local:ContainerControl.Another>
<local:AnotherControl SomeProperty="{Binding ElementName=masterContainerControl, Path=SomeProperty"/>
</local:ExplorerBase.AddressBar>
<local:ContainerControl.Some>
<local:SomeControl SomeProperty="{Binding ElementName=masterContainerControl, Path=SomeProperty"/>
</local:ContainerControl.Some>
</local:ContainerControl>
</UserControl>
This, of course, all assumes MasterContainerControl, ContainerControl, AnotherControl, and SomeControl all have a DependencyProperty called SomeProperty, and then the bindings seal the deal.
Note: Make sure the default values are defined in MasterContainerControl because those will override the values MasterContainerControl binds to.
If I misunderstood your issue, please let me know.

Import external Viewbox to UserControl

I have a UserControl where I want to add a Viewbox. The Viewbox is in an other xaml-file in my project. I tried a lot (something like ResourceDictionaries) ... but failed. Here is my minimal example:
UserControl:
<UserControl ......>
<Grid>
<!--Here I want the Viewbox (MyPicture.xaml)-->
</Grid>
</UserControl>
MyPicture.xaml
<Viewbox Width="16" Height="16" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Rectangle ... />
</Viewbox>
Hope anybody can help me.
As I can understand you need to re-use the view box, if so please try the next solution as a start point to your research.
Xaml code:
<Window x:Class="ResourceDictionaryProblemHelpAttempt.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">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" ContentTemplate="{StaticResource DataTemplateWithViewBox}"></ContentControl>
<ContentControl Grid.Row="1" ContentTemplate="{StaticResource DataTemplateWithViewBox}"></ContentControl>
<ContentControl Grid.Row="2" ContentTemplate="{StaticResource DataTemplateWithViewBox}"></ContentControl>
</Grid>
Resource dictionary code
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="DataTemplateWithViewBox">
<Viewbox Width="16" Height="16">
<Rectangle Width="16" Height="16" Fill="Tomato" Stroke="Black" StrokeThickness="1"></Rectangle>
</Viewbox>
</DataTemplate>
App.xaml code
<Application x:Class="ResourceDictionaryProblemHelpAttempt.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>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ViewPortContainingResourceDictionary.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Regards.
In the resource dictionary code, instead of using (code) , I want to just call the viewbox file. Especially since I have like 2000 lines of code and 30 different view box files. For example, it would be something like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DataTemplate x:Key="DataTemplateWithViewBox">
Get file information of viewbox1.xaml
</DataTemplate>
<DataTemplate x:Key="DataTemplateWithViewBox2">
Get file information of viewbox2.xaml
</DataTemplate>

Categories