Anything defined inside ResourceDictionary must be available as static resource

My VS has some issued which was driving me crazy. I declared a resource (an object) in a resource dictionary and gave it a key. This resource dictionary was external and was referenced via MergedDictionaries. When i tried referencing that resource via its key, I was getting compile time error saying resource not found. This could lead to a lot of confusion for beginners. Please note that whether you define the resource inline, or at parent container(i.e grid/stackpanel etc) or at usercontrol/windows level or even at Application level, it must be available to be referenced in a consistent manner irrespective of its scope and definition

e.g.

<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 x:Name="Window"
 Title="MainWindow" Height="677" Width="686.194">
 <Grid x:Name="Grid">
 <Grid.Resources>
 <ResourceDictionary>
 <ResourceDictionary.MergedDictionaries>
 <ResourceDictionary Source="Dictionary1.xaml"></ResourceDictionary>
 </ResourceDictionary.MergedDictionaries>
 </ResourceDictionary>
 </Grid.Resources>

 <ListBox Name="ItemsControl" ItemsSource="{Binding ElementName=Window, Path=Collection}" ItemTemplateSelector="{StaticResource ViewTemplateSelector}" Margin="0,0,328,0"/>
 <Button Content="Open View One" HorizontalAlignment="Left" Margin="450,73,0,0" VerticalAlignment="Top" Width="95" Click="Button_Click"/>
 <Button Content="Open View Two" HorizontalAlignment="Left" Margin="450,145,0,0" VerticalAlignment="Top" Width="95" Click="Button_Click_1"/>
 </Grid>
</Window>

 

The above code refereneces a ViewTemplateSelector resource which is defined in an external dictionary called Dictionary1.xaml. Now even if this resource is moved to App.xaml or inline within the window itself, i shouldn’t need to have to change my {StaticResource ViewTemplateSelector} markup at all

I sorted the bug in my VS but I thought if the same happens to a novice WPF learner the it might change his fundamental understanding on how resources are referenced.

Advertisements

Working with DataTemplateSelector

Hello,

When you are working with DataTemplateSelector, make sure that you call the InitialiseComponent() method at the end of the constructor in codebehind.  Have a look at the following code:

 public partial class MainWindow : Window
 {
 public MainWindow()
 {
 

 Collection = new ObservableCollection<INotifyPropertyChanged>();
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());
 Collection.Add(new ViewModel1());
 Collection.Add(new ViewModel2());

 InitializeComponent();  //Don't put this as 1st line

 }


 public ObservableCollection<INotifyPropertyChanged> Collection { get; set; }
 
 }

If I just move the call to InitialiseComponent() at the begining of the constructor as the first statement, i don’t get any runtime errors or even any exception on output window but my view renders blank. The main cause being that the binding is already done before InitialiseComponent() and if i set the Collection property after that, it doesn’t do anything because the opportunity has passed.

My Collection property is bound to an ItemsControls in XAML and this ItemsControl uses an ItemTemplateSelector to select the correct DataTemplate for the showing the view.

 

Be careful with Data Template markup

This one is rather for WPF beginners but even after working on WPF for few years, I happened to make this mistake and overlooked it. So just wanted to highlight it for benefit of others…..

When you define a DataTemplate, make sure that you define the x:Key attribute before any other attributes, otherwise it will not get picked up because of the ForwardOnly usage policy of static resource.  I tried the following:

<DataTemplate DataType="wpfApplication1:ViewModel1" x:Key="DataTemplate1" >
 <wpfApplication1:View1/>
 </DataTemplate>

and it gave me the famous error:  “Cannot find resource named ‘DataTemplate2’. Resource names are case sensitive.”

Just by changing the order of the x:Key attribute and putting it before DataType attribute, solved this error. So be careful 🙂

Have a nice day!

.net crosses over the net

On Wednesday, Microsoft Corp. reinforced its commitment to cross-platform developer experiences by open sourcing the full server-side .NET stack and expanding .NET to run on the Linux and Mac OS platforms. Microsoft also released Visual Studio Community 2013, a new free edition of Visual Studio that provides easy access to the Visual Studio core toolset. The announcements kicked off Microsoft’s Connect (); event, where the company released Visual Studio 2015 Preview and .NET 2015 Preview.

“With billions of devices in the market today, developers need tools that target many different form factors and platforms,” said S. Somasegar, corporate vice president, Developer Division, Microsoft. “Through Visual Studio and .NET we are committed to delivering a comprehensive end-to-end solution for developers to build and manage applications across multiple devices and platforms.”

For more information visit here:  .net goes open source

 

Binding directly to a public property of a collection inside ViewModel

You create a WPF window in the application. You add the following code segment to the application.
public class ViewModel
{
public CollectionView Data { get; set; }
}
public class BusinessObject
{
public string Name { get; set; }
}
The DataContext property of the window is set to an instance of the ViewModel class. The Data property of
the ViewModel instance is initialized with a collection of BusinessObject objects. You add a TextBox control
to the Window. You need to bind the Text property of the TextBox control to the Name property of the
current item of the CollectionView of the DataContext object. You also need to ensure that when a binding
error occurs, the Text property of the TextBox control is set to N/A. Which binding expression should you
use?

A. { Binding Path=Data/Name, FallbackValue=’N/A’ }
B. { Binding Path=Data.Name, FallbackValue=’N/A’ }

I used to think that it’s Data.Name, since we intuitively feel the ‘.’ syntax is the correct way to dig deeper into an object. Actually, that’s not the case in this scenario. The object collection in the view model is not bound first to an items control like combobox. If that was the case, then inside each combo box item you could easily call Name directly and the binding would cascade correctly. Here, we are directly trying to get to second level of object hierarchy and therefore the way to do it is to use XPath style syntax: Data/Name, and this will grab the first item in the collection  and bind its Name property to our textbox’s text. Even, if you add 10 textboxes, all will still grab the first item with this syntax.

MEF Error: Activation error occured while trying to get instance of type

MEF Error: Activation error occured while trying to get instance of type <typename>, key “”
I had this error and tried various fixes. The thing that fixed it was removing the string parameter from the Export Attribute above the classname.
The following gave the error
[Export(“VM”)]
[PartCreationPolicy(CreationPolicy.Shared)]
public class VM
{
}

 

The following worked like a charm 🙂
[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public class VM
{
}