WPF project within another WPF project. Commands not working - wpf

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

Related

How can I use WPF menus and dialog boxes in F#?

I've been trying to find an example of using XAML and F# - without C# - to set up traditional menus and dialog boxes. Everything I can find online either uses C# or it is old, before the most recent versions of F# and .NET. Can anyone suggest an example I can look at? Thanks.
When you try to learn WPF, you come across many C# examples based on "good old" code behind rather than MVVM or MVC. The following explains how to quickly create an F# WPF code behind application. Using this, it becomes easier to experiment with all those examples.
Create an F# console application.
Change the Output type of the application to Windows Application.
Add FsXaml from NuGet.
Add these four source files, and arrange them in this order.
MainWindow.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="First Demo" Height="200" Width="300">
<Canvas>
<Button Name="btnTest" Content="Test" Canvas.Left="10" Canvas.Top="10" Height="28" Width="72"/>
</Canvas>
</Window>
MainWindow.xaml.fs
namespace FirstDemo
type MainWindowXaml = FsXaml.XAML<"MainWindow.xaml">
type MainWindow() =
inherit MainWindowXaml()
let whenLoaded _ =
()
let whenClosing _ =
()
let whenClosed _ =
()
let btnTestClick _ =
this.Title <- "Yup, it works!"
()
do
this.Loaded.Add whenLoaded
this.Closing.Add whenClosing
this.Closed.Add whenClosed
this.btnTest.Click.Add btnTestClick
App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
App.xaml.fs
namespace FirstDemo
open System
open System.Windows
type App = FsXaml.XAML<"App.xaml">
module Main =
[<STAThread; EntryPoint>]
let main _ =
let app = App()
let mainWindow = new MainWindow()
app.Run(mainWindow) // Returns application's exit code.
Delete the Program.fs file.
Change the Build Action to Resource for the two xaml files.
Add a reference to the .NET assembly UIAutomationTypes.
Compile and run.
You can't use the designer to add event handlers. Simply add them manually in the code behind.
StackOverflow is possibly not the best place to post complete demos like this one, especially if this spins off more questions along the same line. If there is another better place, e.g. a public repo for this kind of thing, please let me know.

XamlParseException using Extended.Wpf.Toolkit in VS extension project

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);
}
}

What makes visual studio's designer kick in for design time support

I have a c# control library which contains my models, viewmodels and views. I hook everything up as I usually do but I do not get any design time feedback from visual studio's designer (blendability).
When I load my assambly in a WPF project and include the view as custom user control I'll get my design time feedback. Unfortunately this WPF Project is only a test shell because the view will live in another app.
It would be more efficient for my dev pipeline if I could have blendability (design time) support in my class library? What makes visual studio kick in to show my design time datacontext?
I even use d:DataContext="{d:DesignInstance dd:DesignViewModel}" in my class library. No design time data in class library.
Try
d:DataContext="{d:DesignInstance dd:DesignViewModel, IsDesignTimeCreatable=True}
There is a blog here that may help you too.
I found it really frustrating having to create either an empty constructor for my viewmodels, or to make derived classes all the time, just to please the WPF designer.
One solution that works for me (tested only with Visual Studio 2013) is using a static property to expose an instance of a design-time view model, for example
C# code
namespace WpfApplication2
{
public class Person
{
public Person(string id)
{
Id = id;
}
public string Id { get; private set; }
}
public static class DesignViewModels
{
public static Person Person
{
get { return new Person("Design time person id"); }
}
}
}
and the XAML
<Window x:Class="WpfApplication2.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:my="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<d:DesignProperties.DataContext>
<x:Static Member="my:DesignViewModels.Person" />
</d:DesignProperties.DataContext>
<TextBlock Text="{Binding Id}"/>
</Window>

Silverlight Won't Load PivotViewer Collection

I'm trying to get a proof-of-concept PivotViewer application up and running, but I can't get the collection to load properly, even in a testing environment. I'm following these instructions:
Building Your First PivotViewer Application
I have a clientaccesspolicy XML file in the root, giving all URIs access. I copied an already existing collection, and have it in the root as well. The collection XML checks out properly.
Whenever I attempt to debug the application, however, it loads but simply displays the URL for the collection, never actually building the PivotViewer.
MainPage.xaml:
<UserControl x:Class="PivotViewer.MainPage"
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:Pivot="clr-namespace:System.Windows.Pivot;assembly=System.Windows.Pivot"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Pivot:PivotViewer x:Name="Pivot" />
</Grid>
</UserControl>
MainPage.xaml.cs:
namespace PivotViewer
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Pivot.LoadCollection("http://localhost:55334/Top_Movies.cxml", string.Empty);
}
}
}
OK, here's a number of ways forward for you.
Firstly, wire up the PivotViewer's CollectionLoadingFailed event before calling the LoadCollection method. This will expose a CollectionErrorEventArgs containing any exceptions.
Secondly, install Fiddler2 and use it to watch what the PivotViewer is requesting. If it's failing to reach certain parts of the pivot collection it will be very obvious.
Let me know what those 2 suggestion bring to light.

Overspecified Namespace in UserControl fails WPF Build

I have a very simple user control, and I'm trying to instantiate it in XAML. I find that when I go a bit overzealous with the namespacing, I run into problems with x:Name.
Here is my UserControl:
<UserControl x:Class="UserControlTest.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="300" Height="300">
<Grid>
<Label Name="Label1">Label</Label>
</Grid>
</UserControl>
Here is the code-behind for the UserControl:
Namespace UserControlTest
Partial Public Class UserControl1
End Class
End Namespace
Now, note that I have the root namespace of my VB.Net project set to "UserControlTest". Knowing that, have a look at my main window:
Here is my main window:
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:UserControlTest.UserControlTest"
Title="Window1" Height="300" Width="300">
<Grid>
<control:UserControl1 />
</Grid>
</Window>
See how the control alias needs to have "UserControlTest.UserControlTest"? That's because I have the root namespace of my project set to UserControlTest, and I have defined the namespace of the UserControl to be UserControlTest, also. If I don't use a namespace for the UserControl, I don't have any troubles.
However, because I have done this, the build fails should I try to apply an x:Name to the UserControl, as follows:
<control:UserControl1 x:Name="test"/>
That will fail the build, with this error:
Type 'UserControlTest.UserControlTest.UserControl1' is not defined.
Can anybody explain why? Do I need to avoid putting my UserControls into namespaces just so I can give them x:Name values? I'd like to manipulate my UserControls from code-behind, and without an x:Name, I'm up the creek. But I don't want to sacrifice namespace usage just to get it!
Thanks very much.
I had the same problem (after rebuilding the project, first it worked fine...). I put UserControl into separate namespace.
What is the namespace defined as in the code-behind of your user control?
If your project was called Foo and you had a folder called Controls inside that project, any new user control added to that folder would be given the namespace Foo.Controls.
Then in your XAML you can reference it like so:
xmlns:Controls="clr-namespace:Foo.Controls"
...
<Controls:UserControl1 x:Name="uc1"/>
It seems like you have a naming issue.
EDIT:
Here's how I'm doing it in a project of mine.
StatusBar.xaml.cs
namespace Client.Controls.UserControls
{
public partial class StatusBar : UserControl
{
...
}
}
StatusBar.xaml
<UserControl x:Class="Client.Controls.UserControls.StatusBar">
</UserControl>
Main.xaml.cs
using Client.Controls.UserControls;
namespace Client
{
public partial class Main : Window
{
...
}
}
Main.xaml
<Window x:Class="Client.Main"
xmlns:UserControls="clr-namespace:Client.Controls.UserControls">
<UserControls:StatusBar x:Name="mainStatusBar" />
</Window>
I encountered the same problem in a vb.net project, and despite trying the suggestions here and elsewhere, could not solve the issue. In fact, I was able to take the exact same code out of our project to a new project, and it worked just fine (as far as I could determine all the configuration in the new project was identical). In the solution provided by David, I notice he is using c# - I am wondering if this is some weirdness associated with vb.net.
In the end, the user control I needed to use was quite simple and I implemented it as a resource ControlTemplate to get around the issue. Sorry I don't have a better answer, I am really not happy wih my findings...

Resources