XamlParseException using Extended.Wpf.Toolkit in VS extension project - wpf

I have an existing WPF application from which I'd like to make a VisualStudio extension.
Basically, I have a xaml window in which I use the library Extended.Wpf.Toolkit for AvalonDock. This application works perfectly without any issue.
I tried to re-use the same window in my extension project and I got XamlParseException on load
Here is the sample code which fails :
<Window x:Class="Company.VisualStudioExtension.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
Title="Window2" Height="300" Width="300">
<Grid>
<xcad:DockingManager AllowMixedOrientation="True" BorderThickness="1">
<xcad:DockingManager.DocumentHeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Test" />
</StackPanel>
</DataTemplate>
</xcad:DockingManager.DocumentHeaderTemplate>
<xcad:LayoutRoot x:Name="_layoutRoot">
<xcad:LayoutPanel Orientation="Horizontal">
<xcad:LayoutAnchorablePane DockWidth="300">
</xcad:LayoutAnchorablePane>
</xcad:LayoutPanel>
</xcad:LayoutRoot>
</xcad:DockingManager>
</Grid>
The exception is highlighted on the following line :
<xcad:LayoutPanel Orientation="Horizontal">
"The method or operation is not implemented."
EDIT
It seems registering all AvalonDock dll in GAC fixes the issue but obviously, it's not an acceptable solution...
I guess these dll are not properly registered while running as an Extension, I propably need to reference them in a specific way... for now, they are referenced in Extension's csproj + CopyLocal=True
EDIT2
Added source code to reproduce the issue https://github.com/MrLuje/VSPackage_NotWorking
There are 2 projects :
a WPF app with a working code in MainWindow
a VS Extension with non-working code in Window1 (in debug, you need to click in Tools > "My Command name")

I found an easier solution, 'ProvideBindingPath' this will add your current extension folder to the resolution folders of dlls.
[ProvideBindingPath]
public sealed class MainWindowPackage : Package
{
}
based on solution purposed in: VSIX - Cannot load file or assembly of a referenced dll
The solution of adding to the gac wont work 'as is'...VSIX extensions dont allow register on the gac, maybe a workaround will be run gacutil.

Followed #Will's answer and went with the following code which works fine :
protected override void Initialize()
{
base.Initialize();
InstallAvalonToGac();
}
private static void InstallAvalonToGac()
{
var dlls = new string[]
{
"Xceed.Wpf.AvalonDock.dll",
"Xceed.Wpf.DataGrid.dll",
"Xceed.Wpf.Toolkit.dll"
};
foreach (var dll in dlls)
{
var fullpath = Path.Combine(Environment.CurrentDirectory, dll);
new System.EnterpriseServices.Internal.Publish().GacInstall(fullpath);
}
}

Related

MahApps.Metro cannot load file or assembly in Visual Studio extension

I am using MahApps.Metro controls in my XAML code for the toolbox in Visual Studio Extension. I installed the package via NuGet, then I tried to add a control into my XAML markup. Below is the code snippet.
<UserControl
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:custom="http://metro.mahapps.com/winfx/xaml/controls"
x:Class="AutoDebug.MyControl"
Background="{DynamicResource VsBrush.Window}"
Foreground="{DynamicResource VsBrush.WindowText}"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="400"
DataContext="{Binding UserControlModel}"
x:Name="AutoDebugWindow">
<Grid Margin="15">
<custom:Tile Content="Tile" HorizontalAlignment="Left" Margin="75,150,0,0" VerticalAlignment="Top" Background="#FF8B00BF"/>
</Grid>
</UserControl>
But I receive the following error no matter what.
A first chance exception of type 'System.Windows.Markup.XamlParseException' occurred in PresentationFramework.dll
Additional information: Could not load file or assembly 'MahApps.Metro, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
I have already tried installing/uninstalling, deleting/adding references but nothing has worked so far.
This is caused by the fact that MahApps.Metro is not included as a reference when the Visual Studio extension is compiled.
I'm not entirely sure why, but if you only use MahApps in XAML, then no reference is included in the compiled assembly. You can check this by unpackaging the extension (it's just a zip file), and opening the assembly in ILSpy. Under the references, MahApps will not be listed.
A workaround for this is to use MahApps somewhere in code. The simplest way to do this is to name the MahApps control that you are using. This generates a field for the control, and that seems to be enough to cause a reference to be included in the assembly.
<Grid Margin="15">
<custom:Tile x:Name="MyTile" />
</Grid>
You can also use an object from the MahApps assembly anywhere else in code (for example, you could create a new object in the constructor of the Package), but giving one of the controls a name is probably the simplest way.

WPF project within another WPF project. Commands not working

I have a project solution that contains 2 WPF projects. Project B is contained, and called, from within project A.
The issue I'm having, is that the button commands on project B MainWindow are not hitting it's corresponding ViewModel. This doesn't happen when I run Project B as a standalone application (everything's fine).
In both Projects A and B, I'm using Galasofts MVVM light framework, housing my view models in the static ViewModelLocator class.
Any idea's would be greatly appreciated.
Thanks
Edit: For simplicity, I've just included 1 button.
ribbon:RibbonControl xmlns:Designer="clr-namespace:Nouvem.LabelDesigner.View.Designer" x:Class="Nouvem.LabelDesigner.View.Designer.DesignerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:systemMessage="clr-namespace:Nouvem.LabelDesigner.View.SystemMessage"
xmlns:loc="clr-namespace:Nouvem.Shared.Localisation;assembly=Nouvem.Shared"
UseLayoutRounding="True"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1200"
Background="White"
DataContext="{Binding LabelDesigner, Source={StaticResource Locator}}" >
<Grid>
<Button Command="{Binding TestCommand}"/>
</Grid>
</ribbon:RibbonControl>
ViewModel
public RelayCommand TestCommand { get; set; }
public LabelDesignerViewModel()
{
if (this.IsInDesignMode)
{
return;
}
this.TestCommand = new RelayCommand(() =>
{
// test - not hitting when called from another project
});
}
`
if you do something like new ProjectB.MainWindow.Show() in Project A, then all logic in Project B/App.xaml.cs and resources in Project B/App.xaml are ignored.
if you run Project A, then Application.Current is ProjectA.App and ProjectB.App is not instantiated.
there are two solutions:
1. Create Project B as library:
create new shared library called Project B Library, which you will reference from Project A as well as from Project B. Project B will be just an exe container.
2. Start Project B as new Process
use Process.Start() method to start Project B. You can interact with Project B trought WCF using netNamedPipeBinding

IntelliSense for Data Binding not working

After a couple of hours trying to debug an issue with data-binding that was caused by a mistyped property in a Binding extension. Once I noticed the mistake, the realization that if IntelliSense was available I may have not made the mistake in the first place. As a Visual Studio user who is used to error/warnings when mistyping a name; perhaps I'm spoiled, but the lack of IntelliSense led to the error.
I did some research and I found that Intellisense for Data Binding is available is Visual Studio 2013 which I'm using (Ultimate edition). I tried creating a simple WPF app following the second example in the blog. Firstly, There appears to be an error in the second example in the blog that resulted compiler error. Prefixing the Type=ViewModel:MainViewModel attribute with d: fixed the compiler error, yet the properties of my View-Model class are still not showing in the Intellisense menu. My code is below and in GitHub.
MainViewModel.cs:
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace IntelliSenseForDataBinding
{
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
Greeting = "Hello World";
Answer = 42;
}
private string _Greeting;
public string Greeting
{
get { return _Greeting; }
set { _Greeting = value; OnPropertyChanged(); }
}
private int _Answer;
public int Answer
{
get { return _Answer; }
set { _Answer = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
MainWindow.xaml:
<Window x:Class="IntelliSenseForDataBinding.MainWindow"
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="450"
d:DataContext="{d:DesignInstance Type=MainViewModel, IsDesignTimeCreatable=True}"
Title="MainWindow" Height="350" Width="525">
<Grid>
</Grid>
</Window>
MainWindows.xaml.cs:
using System.Windows;
namespace IntelliSenseForDataBinding
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new MainViewModel();
InitializeComponent();
}
}
}
Here's the evidence that is not working:
I would expect to see an item for the 'Greeting' property in the IntelliSense menu. Any suggestions on why it's not there? I've also tried resetting the Visual Studio settings to default, just in case.
In addition, any suggestions on additional methods for preventing or detected mistyped property names in Binding attributes?
I opened your GitHub project in Visual Studio 2013 and I got the same behavior; no IntelliSense for bindings.
The design data is the key to the binding resolution which is failing, so I recommend this:
Add your project namespace to your Window element: xmlns:local="clr-namespace:IntelliSenseForDataBinding" which can help resolve the location of VM.
Change your d:DataContext to use the local namespace instead of d:Type, essentially providing the location of the type you're trying to use: d:DataContext="{d:DesignInstance local:MainViewModel, IsDesignTimeCreatable=True}"
Clean, Build, and Test
Proof:
I know I am late, but Kcvin's answer really helped me a lot and I would like to add that some classes can also use DataType that helps IntelliSense do its magic.
example:
<DataTemplate x:Key="ItemTemplate" DataType="entities:Item">
<Grid Height="60">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text=""
Style="{StaticResource MediumIconStyle}"
Margin="{StaticResource XSmallLeftMargin}"
AutomationProperties.Name="List item icon" />
<StackPanel
Grid.Column="1"
Margin="{StaticResource SmallLeftMargin}"
VerticalAlignment="Center">
<TextBlock Style="{StaticResource ListTitleStyle}" Text="{Binding Name}" />
<TextBlock Style="{StaticResource ListSubTitleStyle}" Text="{Binding Description}" />
</StackPanel>
</Grid>
</DataTemplate>
I hope this helps someone in the future.
UPDATE:
This issue has been resolved in the latest version of Visual Studio (v16.8 and higher). Simply upgrade to the latest version. Hopefully this issue stays fixed.
EDIT:
The visual studio team is currently yet to provide a stable solution to this issue. According to this ticket a fix is available in Visual Studio 16.8 Preview 3. For the meantime, you can consider other creative workarounds present.
If none of the answers here worked for you, a possible way of troubleshooting this issue would be to use the Visual Studio Designer.
Take your caret to a XAML element.
Click on the Properties Tab (or simply press F4)
Go to the DataContext property. If it appears to be empty, try pressing the New button.
If your designer gracefully crashes (like mine did), try to do more debugging from there.
In my case the error looked like this: Could not resolve type 'System.Runtime.CompilerServices.TupleElementNamesAttribute' in assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
Which led me to this question and the installation of the System.Runtime nuget, and a few other changes.
Once the Properties tab is able to correctly identify your ViewModel Intellisense should start working property. If it doesn't, try restarting Visual Studio.
Update Visual Studio to the latest versions, if you are using VS2019.
This will resolve the issue.

Control event not firing from class linked to resource dictionary wpf

Hi I am attempting to attach a function to text box used for entering some input information which is loaded to an interface from resource dictionary. Here is the XML,
<ContentControl>
<Grid>
<Image s:DesignerItem.Code ="1773" IsHitTestVisible="False" Stretch="Fill" Source="../Images/addition.png" ToolTip="Addition" />
<TextBox Height="57" Width="56" Margin="13,13,130,13" BorderThickness="0" FontSize="45" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" TextChanged="msg_TextChange" KeyUp="msg_MouseDown"/>
<TextBox Height="57" Width="56" Margin="132,13,12,13" BorderThickness="0" FontSize="45" HorizontalAlignment="Center" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" KeyDown="msg_MouseDown"/>
<Button MouseDown="msg" Width="50" Height="20">ck</Button>
</Grid>
</ContentControl>
From the above code, I attempted to use a few different types of control events. I successfully linked the class my functions are going to be placed in using the following lines to link the class to the resource dictionary.
x:Class="DiagramDesigner.CodeBuilding"
x:ClassModifier="public"
Here is the code for the class I am using,
public partial class CodeBuilding : ResourceDictionary
{
public CodeBuilding()
{
InitializeComponent();
}
public void msg_TextChange(object sender,EventArgs e)
{
MessageBox.Show("oh no, you've got me ...");
}
public void msg(object sender, MouseEventArgs e)
{
MessageBox.Show("oh no, you've got me ...");
}
}
As you can see, I am just using a simple message to indicate if the event has been fired, the project successfully builds and runs fine, but when I attempt to trigger any of the
events used in the XML the function tied to the event does not fire at all.
I am not certain if this is the best method of linking a function to an event loaded by a resource dictionary, but can anyone provide some guidance to this problem I am experiencing.
XAML file should be dependent on its partial code behind file for events to work.
Make sure Build Action for code behind file is set as Compile.
Also open your .csproj file in notepad or in any text editor and make sure DepedentUpon attribute is set on XAML file. It will look like this:
<Compile Include="CodeBuilding.xaml.cs">
<DependentUpon>CodeBuilding.xaml</DependentUpon>
</Compile>
On a side note, simple steps to make it work like that are:
Add a blank UserControl in your project. It will automatically do this work for you which I mentioned above.
All you need to do is simply change the XAML file to ResourceDictionary. (Replace UserControl to ResourceDictionary).
And in code behind just change the base class from UserControl to ResourceDictionary.

VS 2012: Failed to create a 'ImageSource' from the text

I am declaring an image within my resource dictionary and then displaying in a user control as follows:
ResourceDictionary.xaml (I am using a style here as I plan to update the image as the user changes what they look at, i.e., company, employee, etc.)
<ImageSource x:Key="CompanyIcon">Images/company_128.png</ImageSource>
<Style x:Key="QuickInfoIcon" TargetType="{x:Type Image}">
<!-- Default Value -->
<Setter Property="Source" Value="{StaticResource CompanyIcon}" />
</Style>
The 'Images' folder is a subfolder of 'Assests'. The 'Assests' folder contains my 'ResourceDictionary.xaml' file and I know the path is correct as I get a designer error if I change the path to something like '../Images/company_128.png'
QuickinfoView.xaml
<UserControl x:Class="SidekickAdmin.Views.QuickInfoView"
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:DesignWidth="500" Height="100"
Background="BlanchedAlmond">
<!-- Setup a grid to house the icon and the info -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Name="InfoIcon">
<Image Style="{StaticResource QuickInfoIcon}" Height="50" Width="50"/>
</Grid>
</Grid>
</UserControl>
When viewing the layout in Visual Studio 2012 designer, everything appears correctly but when I run the program I get an error of "XamlParseException occurred: Failed to create a 'ImageSource' from the text 'Images/employee_128.png'." on the ResourceDictionary line with ImageSource.
If I change ImageSource to use a different image it updates as expected within VS2012 designer but then get the same error when trying to run the program.
I have set the Build Action to 'Embedded Resource' on the Resource.resx file but this hasn't fixed the issue.
Any idea on why I am getting the XamlParseException when I try to run this program?
As a side question, when I incorporate images in my program should the image itself (the file) be visible in the bin/debug folder somewhere or is this information hidden with one of the files in bin/debug?
I had the same issue.
You may have a try for what fixed my issue.
Add the file into your project within the Solution Explorer.
I recommend to add folders too dependend on the relative path of your file to the project file.
Then go to:
BUILD -> clean Solution
Finish.
I, too, ran afoul of this issue. Not a single suggested provided by this or any community, most of which were verbatim statements about PACK uri's and other approaches solved the problem. Sadly, for all the enthusiasm people show in answering, most of them haven't a clue on how to fix it.
Setup: 1 solution, 2 projects.
Project 1 was a class library containing resource dictionary containing a list of BitMapSource entries pointing to the local relative path to the images contained below itself.
Example:
<BitmapSource x:Key="RedoImage">Images/Redo.png</BitmapSource>
Project 2 was a WPF application which referenced that class library and which used the MergedDictionary to load the dictionary from the other assembly:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/WPFResourceLibrary;component/Resources/images.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
In a form in the WPF Application project, I dropped a simple IMAGE control on the form. Under it's source property I could select, under LocalResources, from the list of BitMapSources (by key) from my images.xaml resource dictionary. Making a selection, the image would appear (as expected).
But lo and behold, upon running the application, I would get the dreaded "Failed to create image source from the text ..." message. I fiddled about trying all of the many suggestions, each with no success. Always either the same error, or, no error, but no image, at run time.
Fed up, I produced my own custom control. I chose to NOT override the image source property, so we might use that where appropriate, but extended it by adding a dependency property called ResourceName. This control looks through all of the BitMapSources and ImageSources recorded and available within the current app domain. Bingo, it works.
The code:
<Image x:Class="WPFResourceLibrary.Controls.ImageFromResource"
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"
>
</Image>
And the Code Behind for it.
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace WPFResourceLibrary.Controls
{
/// <summary>
/// ImageFromResource - an extension of the standard Image control that properly handles binding Resource to an Image from a Resource
/// </summary>
public partial class ImageFromResource : Image
{
public ImageFromResource()
{
InitializeComponent();
DependencyPropertyDescriptor imageDescriptor = DependencyPropertyDescriptor.FromProperty(ImageFromResource.ResourceNameProperty, typeof(ImageFromResource));
if (imageDescriptor != null)
{
imageDescriptor.AddValueChanged(this, delegate { SetImage(); });
}
}
public static DependencyProperty ResourceNameProperty = DependencyProperty.Register("ResourceName", typeof(ImageSource), typeof(ImageFromResource), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
[Description("Resource String of the Target Image."), Category("Appearance")]
public ImageSource ResourceName
{
get { return (ImageSource)GetValue(ResourceNameProperty); }
set
{
SetValue(ResourceNameProperty, value);
}
}
private void SetImage()
{
if(ResourceName != null)
this.Source = new BitmapImage(new Uri(ResourceName.ToString()));
}
}
}
Thus, providing the functionality expected of the standard image, without the issues arising.
Note, this was performed in Visual Studio 2012 with SP3.
Paul

Resources