How to specify path for file from different project in WPF? - wpf

I've got two projects in WPF and one project is the main one and the second one is just for testing (it uses files of the main project - files are added via Project -> add -> Existing items... -> selected file -> add as link so that the file is only in the main project really).
Folders with projects are these:
C:\Work\...\Projects\Main
C:\Work\...\Projects\XXXTestProject
where XXX stands for different parts of the Main project which I test separately.
I've got the code:
<Window x:Class="Sokoban.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Sokoban"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="Window1" Height="559" Width="419">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GameDesk.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Rectangle local:GameDeskProperties.FieldSize="30" Name="myrect" Style="{DynamicResource GameDesk}" MouseEnter="Rectangle_MouseEnter" />
</Grid>
</Window>
... which should use XAML resources from GameDesk.xaml which is in the main project and it seems that I can't use Pack URI (http://msdn.microsoft.com/en-us/library/aa970069.aspx). How can I specify the file?
Should I use absolute path? (C:\Work...\Main\Resources\GameDesk.xaml)
Or is there any other way?
Thank you for help!

MSDN link here
Use a pack:// URI of the form:
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml
if the XAML is in a referenced assembly
or
pack://siteoforigin:,,,/Subfolder/SiteOfOriginFile.xaml
if the XAML is loose and copied to the bin folder.

Related

IOException when referencing App.xaml's ResourceDictionary

I'm trying to reference App.xaml's ResourceDictionary from a separate WPF window. I want to use resources from there in different windows, and this seems like the recommended way to do it. Unfortunately, I don't seem to be able to effectively reference App.xaml from the other window. Here is my App.xaml:
<Application x:Class="View.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ViewModel="clr-namespace:ViewModel;assembly=ViewModel"
xmlns:local="clr-namespace:View"
StartupUri="ClockView.xaml">
<Application.Resources>
<ResourceDictionary>
<local:PriorityToIconConverter x:Key="PriorityToIconConverter" />
</ResourceDictionary>
</Application.Resources>
Notes: I'm not using MainWindow, so I've replaced the startup URI with a form that always comes up. I noted that in some other answers, the location of MainWindow is sometimes the issue. In my case, I haven't seen any difference between using ClockView or MainWindow. Both ClockView and MainWindow exist in the root namespace, MainWindow is just never loaded. I also have more resources, but I've removed them for the sake of conciseness.
Here's a simplified example of the code where I'm trying to reference the ResrouceDictionary from App.xaml:
<local:AssistantWindow
x:Class="View.AutomatorView"
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:properties="clr-namespace:View.Properties"
xmlns:local="clr-namespace:View"
mc:Ignorable="d"
Title="Tool"
x:Name="Tool"
Background="Transparent"
Height="600"
Width="450"
Topmost="{Binding Source={x:Static properties:Settings.Default}, Path=ToolAlwaysOnTop}"
MinHeight="515"
MinWidth="150">
<Window.Resources>
<ResourceDictionary Source="App.xaml" />
</Window.Resources>
Again, this is simplified to be concise. When I try to load this form, I get the exception:
System.Windows.Markup.XamlParseException: ''Set property 'System.Windows.ResourceDictionary.Source' threw an exception.' Line number '21' and line position '10'.'
Inner Exception
IOException: Cannot locate resource 'tool/app.xaml'.
The view for "Tool" is located in a folder that is also named "Tool." However, the xaml and code behind don't reference this namespace, I'm just using the folder to organize my classes. It looks like it's looking for App.xaml in the folder the view resides in. App.xaml resides in the root namespace (View). I've tried modifying the source in the xaml for Tool to:
- View.App.xaml
- View:App.xaml
- View/App.xaml
How can I get this reference to work, so I can share resources throughout my application? Thank you.
You can't load App.xaml like you're trying to do because it's not actually a ResourceDictionary. You can only specify ResourceDictionary files as the target of Source.
However, if you declare a resource in App.xaml, you can reference it anywhere without needing to load the file it's in. That's done for you automatically. Therefore, you can reference your converter at any time with {StaticResource PriorityToIconConverter}.
Note that if you moved it from the default starting location (the base project folder) you may have to update its location. Right click your project, then Properties. Navigate to the "Application" tab (should be the uppermost element on the left-hand sidebar) and look for the "Startup object" field. Set that to [ProjectName].[Namespace?].[Namespace?].App. When I tested it, mine worked without needing to manually change the location, but your setup may be different.

Use Resource Dictionary Styles in my class library project without merging dictionaries

I am creating a class library project that will contain WPF user controls. My Requirement is that all controls have the same style. My project looks like:
Things I have done in order to solve this problem:
Added all references needed by a WPF application System.Xaml, WindowsBase, etc.. so that I can have wpf controls in my class library project.
In AssemblyInfo.cs I have added:
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
Added ResourceDictionary1.xaml To the project adding the style.
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush x:Key="Brush1" Color="#FF19199E"/>
</ResourceDictionary>
Now if I want to use a style on my UserControl1.xaml I do:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid >
<Rectangle Fill="{StaticResource Brush1}" />
</Grid>
I know it works great but here is the catch. Every time I create a new userControl I will have to merge the dictionary. On a regular WPF application I could just merge the dictionary once on App.xaml and I will be able to use that dictionary on my entire application. How can I avoid having to merge the dictionary every time I create a new userControl? If I plan on addying a new resource dictionary I will have to go to all userControls and merge another dictionary. Perhaps I wrote the question title incorrectly and my question should have been how can I add a App.xaml file to a class library project
You should replace the source value ResourceDictionary1.xaml like the follow:
Source="pack://application:,,,/ControlsDLL;component/ResourceDictionary1.xaml">
or just simple as following:
<UserControl.Resources>
<ResourceDictionary Source="pack://application:,,,/ControlsDLL;component/ResourceDictionary1.xaml"></ResourceDictionary>
</UserControl.Resources>

WPF binding to external style

I have found a framework called VIBlend http://viblend.com/products/net/wpf/controls/free-wpf-controls.aspx. I have downloaded it and there is a dll file containing styles. It contains a dll which contains styles. One of these Styles is contained in a file called ListBox.xaml (compiled in the dll).
It contains a few styles. One of them is declared like this:
Now i am wondering how I can use this style. If created a reference to that dll but now?
I tried this one but it does not work...
<UserControl.Resources>
<ResourceDictionary x:Key="listBoxStyle" Source="Office2010SilverListBoxStyle"/>
</UserControl.Resources>
<ListBox x:Name="listBox" Style="{StaticResource listBoxStyle}">
Try this:
<Application.Resources>
<ResourceDictionary
Source="/PutDllNameHere;component/ListBox.xaml" />
</Application.Resources>

How can i make a prefix so i can address a folder in xaml

I always have problems making new prefixes in xaml. Most of the time, i get the message that the URI cannot be found in the assembly. My setup:
I have a WPF project (in a solution with class libs and asp.NET projects) with a MainWindow.xaml file. The XAML starts with : Window x:Class="MainWindow" ... .
So as default, there's no namespace given to it. In that same project i made a folder "Folder". In that folder, i have resx-files. What i need to do is make a prefix in xaml so i can address those files. I was thinking of :
xmlns:p="clr-namespace:WpfApplication.Folder"
and then for my controls
<Label Content="{x:Static p:NameResxFile.KeyName></Label>
However, the prefix generates the "URI cannot be found in the assembly" error. I'm i just failing at making prefixes?
Thanks in advance.
EDIT
If you cannot make a namespace ref to a folder, what is happening here?
xmlns specifies namespaces, it does not bother with folders or files, if you need access to an external resource you can load it into your control's resources via ResourceDictionary.
There was something like this i think:
<Window.Resources>
<ResourceDictionary x:Key="ExternalRes" Source="Folder/File.xaml"/>
....
</Window.Resources>
To reference an element of resource dictionary you should add that dictionary to your control's Resources collection or register it in the App.xaml file. After that you could just use StaticResource extension to get access to the element. Your code will look like this:
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Folder/NameResxFile.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- ... -->
<Label Content="{StaticResource KeyName}"/>
Things get trickier if you want to put the resource dictionary to another assembly and reference it. For this purpose refer to PackURIs in WPF article.

WPF: Changing MediaElement source with ResourceDictionary

I want to use background music in my WPF Application.
Like you can see here: How to do background music for my WPF-Application?
So I use a MediaElement.
Now I want to change the source of it while running the Application.
I'm already doing something similar with some background pictures. There I have different ResourceDictionaries that I'm switching to show different "themes".
One of my dictionaries looks like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ImageBrush x:Key="Backgroundpic" ImageSource="picture.png"/>
...
</ResourceDictionary>
So I can use it in the xaml like this:
...
<Grid x:Name="Bg" Background="{DynamicResource Backgroundpic}"/>
...
But HOW can I do that with my MediaElement-Source that I can use it like this:
<MediaElement x:Name="myMediaElement" Source="{DynamicResource ???}" />
I just don't know what to write into my ResourceDictionary.
Source is a Uri, so you need your resource to be a Uri. (Note that System.Uri is in the System assembly, not mscorlib, so it needs a different XML namespace than you would use for types like String):
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=System">
<sys:Uri x:Key="mediaSource">something.mp3</sys:Uri>
Then you can reference it with Source={DynamicResource mediaSource}.

Resources