I have created very small WPF application and facing one problem. I have below classes.
Employee.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StaticResourceVsDynamicResource
{
public class Employee
{
public string strName;
public int nId;
public Employee()
{
strName = "Default name";
nId = -1;
}
public string Name
{
get{return strName;}set{strName = value;}
}
public int ID
{
get{return nId;}set{nId = value;}
}
}
}
MainWindow.xamal.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace StaticResourceVsDynamicResource
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
this.Resources["objEmployee"] = new Employee { Name = "Changed employee", ID = 100};
this.Resources.Add("myBrush",new SolidColorBrush(SystemColors.GrayTextColor));
}
}
}
MainWindow.xamal
<Window x:Class="StaticResourceVsDynamicResource.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StaticResourceVsDynamicResource"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<x:ArrayExtension Type="{x:Type sys:String}" x:Key="objNames">
<sys:String>A1</sys:String>
<sys:String>A2</sys:String>
</x:ArrayExtension>
<local:Employee x:Key="objEmployee"></local:Employee>
</Window.Resources>
<Grid>
<Grid Height="100" HorizontalAlignment="Left" Margin="281,12,0,0" Name="grid3" VerticalAlignment="Top" Width="200" >
<ComboBox ItemsSource="{StaticResource ResourceKey=objNames}" Height="23" HorizontalAlignment="Left" Margin="48,37,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" />
</Grid>
</Grid>
Above xaml code is intresting. When I build this code I didn't get any error. For whatever reason I just shuffle position of <x:ArrayExtension> and <local:Employee> and I start getting below error.
The name 'InitializeComponent' does not exist in the current context
When I am declaring <local:Employee> before <x:ArrayExtenion> then only I am getting this error. I am sure this has to do something with namespace, but I am not able to figure it out. See the below code which is causing compilation error.
<Window.Resources>
<local:Employee x:Key="objEmployee"></local:Employee>
<x:ArrayExtension Type="{x:Type sys:String}" x:Key="objNames">
<sys:String>A1</sys:String>
<sys:String>A2</sys:String>
</x:ArrayExtension>
</Window.Resources>
Can anyone help? Seems to be a strange problem but it is...
Regards,
Hemant
I've had the same problem. The way I resolved it was by changing the build action of the XAML file to Page.
To credit the source where I found the solution:
http://blog.mahop.net/post/Compile-Error-for-WPF-Files-The-name-InitializeComponent-does-not-exist-in-the-current-context.aspx
Related
I recently took up the task of learning how to build an application in WPF, and landed on ReactiveUI as my MVVM framework. I am currently trying to practice implementing the Router in my application, and I'm finding that despite following the examples from "You, I, and ReactiveUI", my RoutedViewHost is not displaying a view, and throws the error:
"System.Exception: 'Couldn't find view for 'LearnReactiveUI.ViewModels.StartupViewModel'.'"
Below is the xaml for my main window (ReactiveWindow), and has a RoutedViewHost as its body
<rxui:ReactiveWindow x:Class="LearnReactiveUI.Views.MainView"
xmlns:rxui="http://reactiveui.net"
xmlns:vms="clr-namespace:LearnReactiveUI.ViewModels"
x:TypeArguments="vms:MainViewModel"
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:local="clr-namespace:LearnReactiveUI.Views"
mc:Ignorable="d"
Title="MainView" Height="450" Width="800">
<Grid>
<rxui:RoutedViewHost x:Name="routedViewHost"/>
</Grid>
</rxui:ReactiveWindow>
Here is my MainViewModel class, which creates a RoutingState and then navigates to a new StartupViewModel
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearnReactiveUI.ViewModels
{
public class MainViewModel : ReactiveObject, IScreen
{
private readonly RoutingState routingState;
public MainViewModel()
{
this.routingState = new RoutingState();
routingState.Navigate.Execute(new StartupViewModel(this));
}
public RoutingState Router => this.routingState;
}
}
And finally here is my code-behind for my MainWindow that binds the Router to the RoutedViewHost
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using LearnReactiveUI.ViewModels;
using System.Reactive.Disposables;
namespace LearnReactiveUI.Views
{
public partial class MainView : ReactiveWindow<MainViewModel>
{
public MainView()
{
InitializeComponent();
this.ViewModel = new MainViewModel();
this.WhenActivated(disposables =>
{
this
.OneWayBind(this.ViewModel, vm => vm.Router, v => v.routedViewHost.Router)
.DisposeWith(disposables);
});
}
}
}
The code for my Startup view is also very simple. Here is the xaml
<rxui:ReactiveUserControl x:Class="LearnReactiveUI.Views.StartupView"
xmlns:rxui="http://reactiveui.net"
xmlns:vms="clr-namespace:LearnReactiveUI.ViewModels"
x:TypeArguments="vms:StartupViewModel"
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:local="clr-namespace:LearnReactiveUI.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Label Content="Startup" HorizontalAlignment="Center"
VerticalAlignment="Center" FontSize="72"/>
</Grid>
</rxui:ReactiveUserControl>
And here is the code for the StartupViewModel
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearnReactiveUI.ViewModels
{
public class StartupViewModel : ReactiveObject, IRoutableViewModel
{
private IScreen hostScreen;
public StartupViewModel(IScreen hostScreen)
{
this.hostScreen = hostScreen;
}
public string UrlPathSegment => "Startup";
public IScreen HostScreen => this.hostScreen;
}
}
There is no code in the code behind as there are no properties I am binding to the view yet.
My code compiles and I have verified that it will successfully instantiate a MainView and MainViewModel. I am trying to figure out where I went wrong.
Any help is appreciated. Thanks!
You need to register your view and viewModel. Please look at routing example.
In my opinion, this change in the MainViewModel constructor should fix the issue:
public MainViewModel()
{
this.routingState = new RoutingState();
// register view and viewModel
Locator.CurrentMutable.Register(() => new StartupView(), typeof(IViewFor<StartupViewModel>));
routingState.Navigate.Execute(new StartupViewModel(this));
}
#Glenn Watson mentions an important thing. The Locator setup should be done in a bootstrap-like class to allow multiple platform coding and to not break DI. You should look at this when you learn the basics.
I know this has been asked before, but still can't wrap my head around any solution that will work for my case. I want to be able to sort the observable collection in this project according to the ItemName. here is the full project https://gist.github.com/NewCoderNotInTown/322274bd7d2fd57bf2ae7784e1315b73.
the aim is to have both lists, the original one and the copied one, sorted alphabetically.
appreciate a solution for this case. as simple as possible for a beginner.
I Edit the question with complete code as advised.
Code for MainWindow.xaml
<Window x:Class="TwoWindows.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:WB="clr-namespace:TwoWindows"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Button Grid.Row="1" Content="Click Me" Width="80" Height="25" Click="ClickMe_Click"/>
<TabControl Grid.Row="0" Margin="10">
<TabItem>
<TabItem.Header>
<StackPanel>
<TextBlock Text="WindowB"/>
</StackPanel>
</TabItem.Header>
<WB:WindowB x:Name="_windowB"/>
</TabItem>
</TabControl>
</Grid>
Code for MainWindow.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TwoWindows
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void ClickMe_Click(object sender, RoutedEventArgs e)
{
var windowBViewModel = new WindowBViewModel("WindowB");
var windowB = new WindowB();
var windowAViewModel = new WindowAViewModel("WindowA", windowBViewModel);
var windowA = new WindowA();
windowA.DataContext = windowAViewModel;
windowA.Show();
_windowB.DataContext = windowBViewModel;
}
}
}
Code for WindowA.xaml
<Window x:Class="TwoWindows.WindowA"
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:local="clr-namespace:TwoWindows"
mc:Ignorable="d"
Title="WindowA" Height="300" Width="600">
<Grid>
<Label Content="{Binding PageTitle}" />
<ListBox ItemsSource="{Binding MyItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox Content="{Binding ItemName}" IsChecked="{Binding IsChecked}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Code for WindowA.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace TwoWindows
{
public partial class WindowA : Window
{
public WindowA()
{
InitializeComponent();
}
}
}
Code for WindowB.xaml
<UserControl x:Class="TwoWindows.WindowB"
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:local="clr-namespace:TwoWindows"
mc:Ignorable="d">
<Grid>
<Label Content="{Binding PageTitle}" />
<ListBox ItemsSource="{Binding MyItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ItemName}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
Code for WindowB.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace TwoWindows
{
public partial class WindowB : UserControl
{
public WindowB()
{
InitializeComponent();
}
}
}
Code for WindowAViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoWindows
{
public class WindowAViewModel : BaseWindowViewModel
{
public WindowAViewModel(string pageTitle, WindowBViewModel windowBViewModel)
{
PageTitle = pageTitle;
MyItems.Add(new MyCustomItemViewModel("Apple", windowBViewModel));
MyItems.Add(new MyCustomItemViewModel("Orange", windowBViewModel));
MyItems.Add(new MyCustomItemViewModel("Banana", windowBViewModel));
}
}
}
Code for WindowBViewModel
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoWindows
{
public class WindowBViewModel : BaseWindowViewModel
{
public WindowBViewModel(string pageTitle)
{
PageTitle = pageTitle;
}
}
}
Code for MyCustomItemViewModel.cs
using PropertyChanged;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoWindows
{
[ImplementPropertyChanged]
public class MyCustomItemViewModel
{
public string ItemName { get; set; }
public bool IsChecked { get; set; }
public WindowBViewModel WindowBViewModelObj { get; set; }
public MyCustomItemViewModel(string itemName, WindowBViewModel windowBViewModel)
{
ItemName = itemName;
WindowBViewModelObj = windowBViewModel;
}
private void OnIsCheckedChanged()
{
if (IsChecked)
WindowBViewModelObj.MyItems.Add(this);
else
WindowBViewModelObj.MyItems.Remove(this);
}
}
}
Code for BaseWindowViewModel.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TwoWindows
{
public class BaseWindowViewModel
{
public string PageTitle { get; set; }
public ObservableCollection<MyCustomItemViewModel> MyItems { get; } = new ObservableCollection<MyCustomItemViewModel>();
}
}
Here's three common ways for sorting from your code.
Manually apply the Sort anytime you add items. I would suggest linq for the actual sorting, although you can build your own. In your specific case, it would look like this :
MyItems.Add(new MyCustomItemViewModel("Apple", windowBViewModel));
MyItems.Add(new MyCustomItemViewModel("Orange", windowBViewModel));
MyItems.Add(new MyCustomItemViewModel("Banana", windowBViewModel));
MyItems = MyItems.Sort(p => p.ItemName);
This assumes you enable the setter so MyItems is not readonly.
In the getter for MyItems, return the collection sorted (and use a backing property for it). This is not really ideal, since you build the sorted collection for each call that is made to the getter. For your code, it would look like this :
public class BaseWindowViewModel
{
public string PageTitle { get; set; }
private ObservableCollection<MyCustomItemViewModel> _myItems = new ObservableCollection<MyCustomItemViewModel>()
public ObservableCollection<MyCustomItemViewModel> MyItems
{
get { return _myItems.Sort(p => p.ItemName); }
}
}
(Recommended) Work with a CollectionViewSource that sits on top of your collection and applies UI-friendly operations like sorting and filtering.
public class BaseWindowViewModel
{
public string PageTitle { get; set; }
private ObservableCollection<MyCustomItemViewModel> _myItems;
public ObservableCollection<MyCustomItemViewModel> MyItems
{
get
{
if (_myItems == null)
{
_myItems = new ObservableCollection<MyCustomItemViewModel>();
_myItemsSorted = CollectionViewSource.GetDefaultView(_myItems)
_myItemsSorted.SortDescriptions.Add(new SortDescription() { PropertyName = "ItemName" });
}
return _myItems;
}
}
private ICollectionView _myItemsSorted;
public ICollectionView MyItemsSorted { get { return _myItemsSorted; }}
}
And then just bind to MyItemsSorted rather than MyItems
You can do this using LINQ, but you'll have to call Sort() when you're done adding or removing items. If that happens a lot with large lists, you may want to look into ObservableCollection.Insert and using your own comparer.
public class BaseWindowViewModel
{
public string PageTitle { get; set; }
public ObservableCollection<MyCustomItemViewModel> MyItems
{
get
{
return _MyItems;
}
}
private ObservableCollection<MyCustomItemViewModel> _MyItems = new ObservableCollection<MyCustomItemViewModel>();
public void Sort()
{
_MyItems = new ObservableCollection<MyCustomItemViewModel>(from i in _MyItems orderby i.ItemName select i);
}
}
Im not 100% this goes with the whole wpf mvvm design pattern but I'm lost on how to do it.
I have a main view in this main view i have ObservableCollection called 'DemoClass_List', each element in the list contains a class 'DemoClass'.
In the wpf for this view i have wrappanel, what i want is for the wrappanel to display a usercontrol for each element, but also to pass the individual class to the element.
Code is below.
***UserControl
public partial class DemoClass_Display : UserControl
{
public DemoClass _demoClass;
public DemoClass_Display()
{
InitialiseComponent();
//Do processing on _demoClass and display relevant info
}
}
***MainView WPF Snippet
<ItemsControl ItemsSource = "{Binding DemoClass_List}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<usercontrol:DemoClass_Display/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The question is, how do i fill the item "public DemoClass _demoClass;" in the usercontrol?
****************Edit****************
This code crashes
****MainView
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public static ObservableCollection<DemoClass> DemoClass_List { get; set; }
public Window1()
{
DemoClass_List = new ObservableCollection<DemoClass>();
DemoClass dc1 = new DemoClass();
dc1.Property1 = 1;
dc1.Property2 = 1;
dc1.Property3 = 1;
DemoClass dc2 = new DemoClass();
dc2.Property1 = 2;
dc2.Property2 = 2;
dc2.Property3 = 2;
DemoClass dc3 = new DemoClass();
dc3.Property1 = 3;
dc3.Property2 = 3;
dc3.Property3 = 3;
DemoClass_List.Add(dc1);
DemoClass_List.Add(dc2);
DemoClass_List.Add(dc3);
InitializeComponent();
}
}
}
***MainViewWPF
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:UserControl="clr-namespace:WpfApplication1"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Window1" Height="300" Width="300">
<Grid>
<ItemsControl ItemsSource="{Binding DemoClass_List}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<UserControl:DemoClass_Display demoClass="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
***UserControl
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for DemoClass_Display.xaml
/// </summary>
public partial class DemoClass_Display : UserControl
{
public static readonly DependencyProperty DemoClassProperty = DependencyProperty.Register("demoClass", typeof (DemoClass), typeof (DemoClass_Display), new PropertyMetadata(default(DemoClass)));
public DemoClass demoClass
{
get { return (DemoClass)GetValue(DemoClassProperty); }
set { SetValue(DemoClassProperty, value); }
}
public DemoClass_Display()
{
InitializeComponent();
Console.WriteLine(demoClass.Property1);
}
}
}
The console crashes as demoClass hasnt been set
You need to create a dependency property in your UserControl:
public static readonly DependencyProperty DemoClassProperty = DependencyProperty.Register(
"DemoClass", typeof (DemoClass), typeof (DemoClass_Display), new PropertyMetadata(default(DemoClass), OnDemoClassChanged));
public DemoClass DemoClass
{
get { return (DemoClass) GetValue(DemoClassProperty); }
set { SetValue(DemoClassProperty, value); }
}
private static void OnDemoClassChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var newDemoClass = e.NewValue as DemoClass;
var demoClassDisplay = (DemoClass_Display)dependencyObject; // you can access this UserControl this way.
if(newDemoClass != null)
{
//Do processing on newDemoClass and display relevant info
}
}
And then you can bind the current item of the ItemsControl in the DataTemplate:
<ItemsControl.ItemTemplate>
<DataTemplate>
<usercontrol:DemoClass_Display DemoClass="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
So inside the UserControl you will use the DemoClass property instead of the field _demoClass. I think that can even be deleted.
In Visual Studio 2013 (fully updated) and Blend 2013, I am not seeing design time data in my UserControl, but I am seeing design time data in the Window that has the UserControl. What follows is a simplified demo of my problem.
The model (color.cs):
using System;
namespace TestWPF {
public class color {
public string name { get; set; }
}
}
The ModelView (colorViewModel.cs):
using System;
using System.Collections.Generic;
namespace TestWPF
{
public class colorViewModel
{
public List<color> colorList;
public colorViewModel()
{
colorList = new List<color>();
colorList.Add(new color() { name = "blue" });
colorList.Add(new color() { name = "red" });
}
}
}
The UserControl code-behind (colorUserControl.xaml.cs):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace TestWPF
{
public partial class colorUserControl : UserControl
{
public colorUserControl()
{
InitializeComponent();
this.DataContext = (new colorViewModel()).colorList;
}
}
}
The UserControl XAML (colorUserControl.xaml):
<UserControl x:Class="TestWPF.colorUserControl"
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="300">
<Grid>
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="True" />
</Grid>
</UserControl>
The Window XAML (MainWindow.xaml):
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
xmlns:view="clr-namespace:TestWPF">
<Grid>
<view:colorUserControl />
</Grid>
</Window>
The Window gets design time data:
But not the UserControl:
How do I get my UserControl to show design time data?
The problem you are having is that you are not actually using design-time data, even in your main window.
When using design-time data, you have two options:
DesignInstance - This is used to help with shaping your datacontext. It will offer you intellisense support with the binding paths.
DesignData - This will let you choose a xaml resource which represents your datacontext with actual sample data.
Unfortunately, you must only select one (they cannot coexist).
Some good resources are listed below:
http://www.arrangeactassert.com/how-to-use-a-designinstance-to-populate-controls-with-design-time-data-in-silverlight-and-wpf/
http://jack.ukleja.com/ddesigninstance-in-depth/
http://karlshifflett.wordpress.com/2009/10/28/ddesigninstance-ddesigndata-in-visual-studio-2010-beta2/
While designing a new WPF application I noticed exceptions not being thrown during data binding for controls with DataTemplates. To test I wrote the following simple user control with as little logic as possible. I'm using .NET 3.5 SP1, VS2008 SP1 running on WIN7.
When the DataContext is set, TestMethod is called and an exception is thrown in the codebehind but the application doesn't break.
Would someone mind explaining what is happening when the DataTemplate is being created? Specifically I'm interested in where the exception goes.
Below is the XAML code:
<UserControl x:Class="WPF2008.DataTemplateQuestion"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
<DataTemplate x:Key="TESTKey">
<Border BorderBrush="Black" BorderThickness="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Text="{Binding Path=Txt}" />
<TextBox Grid.Row="1" Text="{Binding Path=Lbl}" />
<TextBox Grid.Row="2" Text="Am I disabled?" />
<TextBox Grid.Row="3" Text="I am disabled." IsEnabled="False" />
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Label x:Name="lblTest" Content="{Binding Path=TestMethod}" ContentTemplate="{StaticResource TESTKey}" />
</Grid>
</UserControl>
Below is the codebehind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPF2008
{
public partial class DataTemplateQuestion : UserControl
{
public DataTemplateQuestion()
{
try
{
InitializeComponent();
lblTest.DataContext = new TestClass();
}
catch (Exception e)
{
// ADDING A BREAKPOINT HERE DOESN'T CATCH THE EXCEPTION
throw e;
}
}
}
public class TestClass
{
public TestValue TestMethod
{
get
{
// BREAKPOINT WILL BE HIT WHEN DEBUGGING BUT THE EXCEPTION DISAPPEARS
throw new Exception("WATCH ME DISAPPEAR");
return new TestValue { Lbl = "Label", Txt = "Text" };
}
}
public class TestValue
{
public string Lbl { get; set; }
public string Txt { get; set; }
}
}
}
Exceptions thrown by data bindings get translated into trace, which are delivered to the DataBindingSource TraceSource, which has a source name of "System.Windows.Data".
You can convert these into exceptions by creating a subclass of TraceListner that throws an exception on a trace, and add it to the Listeners collection of the TraceSourceSource. This can be done either in code or in your App.config file.
Here is how you would do it in code:
System.Diagnostics.PresentationTraceSources.DataBindingSource.Listeners.Add(
new MyTraceListener());
See TraceSource and TraceListener documentation and samples for more details.
Exceptions get eaten by data bindings, and result in the data binding being disabled (I'm not 100% sure this is the case here, I'm too lazy to put it into VS).
Another possibility is that you may be hitting http://support.microsoft.com/kb/976038 if you are running a 64-bit OS.