23

I have a template defined in a XAML file named 'MyTemplate.xaml'. This template is using a code-behind file named 'MyTemplate.cs'.

Mytemplate.xaml:

<ResourceDictionary x:Class="Project.Templates.MyTemplate">
    <DataTemplate ... />
</ResourceDictionary>

MyTemplate.cs:

namespace Project.Templates
{
    public partial class MyTemplate : ResourceDictionary
    {
        ...
    }
}

In the Visual Studio Solution Explorer, these two files are side by side. What I would like to do is to put these two files together, just like with a Control and its code-behind.

What I have: enter image description here

What I would like to have: enter image description here

What is the best way to do that? Thank you.

Morgan M.
  • 846
  • 2
  • 9
  • 27
  • Why do you want to do that... I mean what is your aim once you have this 'merged' file? – Sheridan Aug 08 '13 at 09:00
  • 1
    It's just clearer in the Solution Explorer. It allows me to see which template file is associated with which template code-behind. Don't you find it useful for Controls? – Morgan M. Aug 08 '13 at 09:05
  • 1
    In that case, please explain how to add an event handler to a template without using code-behind... – Morgan M. Aug 08 '13 at 09:23
  • I've added a suggestion answer. – Sheridan Aug 08 '13 at 09:24
  • 3
    @Sheridan, "code-behind pages are old school", really? Just because you use the MVVM pattern doesn't mean that you can't use code-behind; there are still many cases where code-behind is the right place to do something, especially if it's purely UI-related. – Thomas Levesque Aug 08 '13 at 09:33
  • @MorganM. I've answered your question regarding responding to an event without code-behind, hope it helps :) – JMK Aug 08 '13 at 09:34
  • @ThomasLevesque, WPF is all about binding whether you use MVVM or not. What I meant was that in WinForms, you *had* to use the code behind, whereas WPF does not follow this pattern. I don't believe that I said that someone can't use the code behind, did I? – Sheridan Aug 08 '13 at 11:12

4 Answers4

41

You need to edit the .csproj file. Find the <Compile> element for MyTemplate.cs, and add a <DependentUpon> element under it:

<Compile Include="MyTemplate.cs">
  <DependentUpon>MyTemplate.xaml</DependentUpon>
</Compile>

See this blog post: make a project item a child item of another

Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
2

This isn't an answer to your initial question, but to this:

In that case, please explain how to add an event handler to a template without using code-behind

You can do this with a ViewModel and an ICommand class.

First you need to create your ViewModel class, make this public and non static with a parameter-less constructor.

Then create another class which implements the ICommand interface:

public class Command : ICommand
{
    public void Execute(object parameter)
    {
        //this is what happens when you respond to the event
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;
}

Add an instance of your command class to your ViewModel class, make this private and expose it through a read-only property:

public class ViewModel
{
    private readonly ICommand _command = new Command();

    public ICommand Command
    {
        get { return _command; }
    }
}

Add your ViewModel as a static resource, in your App.xaml file:

<Application.Resources>
     <wpfApplication1:ViewModel x:Key="ViewModel"/>
</Application.Resources>

Set your DataContext of your XAML file to your ViewModel:

<Window DataContext="{StaticResource ViewModel}">

Now respond to your event by binding to the Command class:

<Button Click="{Binding Command}"></Button>

Boom, no code-behind. Hope this helps.

JMK
  • 27,273
  • 52
  • 163
  • 280
  • This is indeed not an answer to my question but I didn't know this way of implementing event handlers without code-behind. Thank you :) – Morgan M. Aug 08 '13 at 09:52
2

Another way is to:

  • Add/Create a new XAML file/item
  • Copy and paste the old .xaml and xaml.cs content to the new equivalent files
  • delete the separate files
  • rename the new file
usefulBee
  • 9,250
  • 10
  • 51
  • 89
0

Easiest way to do this is:

  1. Exclude unlinked files from project
  2. Make sure 'show all files' is enabled in solution explorer
  3. Select the container file (.xaml not xaml.cs in this case), right-click and include in project. Should be added to the project with the link repaired.
Dan
  • 51
  • 5