In the xaml code i get an error telling cannot create an instance of
this AllEmployeeViewModel class file, actually this class file exists in the solution folder when i type scr: the intellsene shows me the class file
<UserControl.Resources>
<scr:AllEmployeeViewModel x:Key="empName"></scr:AllEmployeeViewModel>
</UserControl.Resources>
<Grid x:Name="MainGrid" Background="White" Width="400"
Height="407" DataContext="{Binding Source={StaticResource empName}}" >
<Grid x:Name="grdAllEmp" DataContext="{Binding Path=EmployeeClass}">
<sdk:DataGrid AutoGenerateColumns="True" Height="274"
HorizontalAlignment="Left" Margin="8,8,0,0"
Name="dgEmployee" VerticalAlignment="Top" Width="385"
ItemsSource="{Binding}"/>
<Button Content="Get All Employees" Height="23"
HorizontalAlignment="Left" Margin="12,288,0,0"
Name="btnAllEmplloyees" VerticalAlignment="Top" Width="381"
Command="{Binding Path=DataContext.GetEmployees,ElementName=MainGrid}"/>
</Grid>
i am trying to bind the data to grid, if i ignore the compile time error and run its gives an error key not found.
please let me know the solutionif you know,working on this issue from past 2days
any help would be great
thanks.
I too had the same issue.
cannot create instance of viewmodel
Just copy this code and place it in ViewModel
public bool IsDesignTime
{
get
{
return (Application.Current == null) ||
(Application.Current.GetType() == typeof(Application));
}
}
//Constructor
public ViewModelClass()
{
if(IsDesignTime == false)
{
//Your Code
}
}
Just add this line in MainPage.xaml.cs page
InitializeComponent();
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
//Code that throws the exception
}
it works fine.
Does your class AllEmployeeViewModel have a zero-argument constructor? WIthout that, Silverlight cannot create an instance of your class.
You have a binding to EmployeeClass. That has to be a collection of some type for this to work, but the name EmployeeClass sounds like a single object and not a collection.
You really needed to post your View Model code as we had to guess this.
I put together a quick example and if the ViewModel contains:
public ObservableCollection<EmployeeClass> Employees { get; set; }
and I populate them with a few sample EmployeeClass objects,
public AllEmployeeViewModel()
{
this.Employees = new ObservableCollection<EmployeeClass>();
this.Employees.Add(new EmployeeClass() { Name = "One" });
this.Employees.Add(new EmployeeClass() { Name = "Two" });
and I change the binding to:
<Grid x:Name="grdAllEmp" DataContext="{Binding Path=Employees}">
It looks like this (no other changes):
I was getting the same error, i will explain it to you hopefully it will help you.
In my ViewModel's constructor i was executing some code, all code was withing below if condition except,
If(!IsInDesignMode)
{
// my code
}
// Problamatic method execution point
Except a method that i wanted to execute every time, but it turns out that you can only execute code if above condition is satisfied else your view model instance will not be created.
So to avoid this you have to do like that:
If(!IsInDesignMode)
{
// my code
// Problamatic method execution point
}
Put all your code inside that condition and everything will be fine.
Note: I was using MVVMLight library along with Model-View-ViweModel pattern.
Related
Hi I build a simple test solution in VS 2012 with two projects.
One is a Class library and the other a WPF application.
Both use .NET 4.5.
In the class library I add an EF element (DataFirst) which maps a simple table.
Next I reference this project in my WPF project.
Add EF from Nuget and using a very simple MVVM like pattern I add a class which looks like this (please note - this is not production code - it's just to reproduce the problem).
public class Class1 {
public static Helper TheHelper { get; set; }
public Class1() {
TheHelper = new Helper();
}
}
public class Helper {
public Helper() {
Nam = "aaa";
}
string connectionString = "metadata=res://*/Mod.csdl|res://*/Mod.ssdl|res://*/Mod.msl;provider=System.Data.SqlClient;provider connection string=\";data source=.\\sqlx8r2;initial catalog=FCdata;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework\"";
public string Nam { get; set; }
#region PCs
private List<PC> m_lPCs;
public List<PC> PCs {
get {
if(m_lPCs == null) {
try {
using(FCdataEntities dE = new FCdataEntities(connectionString)) {
m_lPCs = dE.PCs.ToList();
}
}
catch(Exception eX) {
m_lPCs = new List<PC>();
m_lPCs.Add(new PC() { Description = eX.Message });
}
}
return m_lPCs;
}
set {
if(m_lPCs != value) {
m_lPCs = value;
//RaisePropertyChanged(() => PCs);
}
}
}
#endregion
I also extended the context class like this:
public partial class FCdataEntities : DbContext {
public FCdataEntities(string strCon) : base(strCon) {
}
}
So I can pass the connection string which I copy from app.config.
In my main window I do a simple binding like this:
xmlns:local="clr-namespace:EFTest"
Title="MainWindow" Height="350" Width="1525">
<Window.Resources>
<local:Class1 x:Key="dG" />
</Window.Resources>
<Grid DataContext="{Binding Path=TheHelper, Source={StaticResource dG} }">
<Grid.RowDefinitions>
<RowDefinition Height="17*"/>
<RowDefinition Height="143*"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding Nam}" />
<ListBox ItemsSource="{Binding PCs}" Grid.Row="1">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Description}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
The solution works fine at runtime.
But in the VS Designer I get an exception shown in my "dummy obect" which I create in the catch block of the property.
Could not load file or assembly 'Windows, Version=255.255.255.255, Culture=neutral, ContentType=WindowsRuntime' or one of its dependencies. Operation is not supported. (Exception from HRESULT: 0x80131515)
What I need is data at design time - and no "dummy data" - instead I want to get it from the DB - avoiding the use of EF (and use linq2sql for an example) works like a charm.
Did I make a mistake with the connection string (or so) - or is there simply a problem in EF 5.0?
This particular error is a known issue in Entity Framework 5 with the Visual Studio & Expression designers and has been fixed in the Entity Framework 6 source code. However there are other design time errors which I haven't been able to resolve which prevent Entity Framework code from running in the designer.
I am using WPF with MVVM. I need some advise on how I can get the progress message to the UI from the following architecture.
UI - File processing window.
ViewModel - Has properties for Message, ProgressValue
The message is bound to the UI textblock to update the ui on what is happening in the background while the user is working on something else.
When the user click Process file, the ViewModel ProcessFile is invoked.
The viewmodel directly does not process any files. It in turn calls a different assembly which does the processing of the file.
Here are the pieces of code (I could not put the actual code here):
XAML:
<StackPanel>
<TextBlock Text="{Binding Message}" />
<ProgressBar MinWidth="250" Height="25" IsIndeterminate="True" />
</StackPanel>
Currently I have it IsIndeterminate. I will change this to show the percentage complete.
ViewModel
private string _message;
public string Message
{
get
{
return _message;
}
set
{
_message=value;
OnPropertyChanged("Message");
}
}
private int _progressValue;
public int ProgressValue
{
get { return _progressValue;}
set
{ _progressValue=value;
OnPropertyChanged("ProgressValue");
}
}
public void StartProcess(string fileName)
{
ThreadStart tStart = delegate()
{
differentAssembly.StartProcess(string fileName);
};
Thread processThread = new Thread(tStart);
processThread.IsBackground = true;
processThread.Start();
}
Now with that said how do I get the progress information from the differentAssembly. This will be a message stating the progress and a percentage.
Thanks for your help.
I had the same question on increasing the progress bar value from different assembly.
Instead of calling thread which of course have good number of advantages I used the Observable pattern. Which uses the delegates and background worker.
If I am right we could use Observable pattern with MVVM.
Let me know if I answered your question.
Could you do something like this?
differentAssembly.StartProcess(fileName, x => ProgressValue = x);
Your StartProcess function is then in charge of updating the progress:
public class DifferentAssembly
{
public void StartProcess(string fileName, Action<int> progressValue)
{
// Initialize progress
progressValue(0);
// Do Some Things
progressValue(25);
// Do More Things
progressValue(50);
// Almost There!
progressValue(75);
// And, I'm Done
progressValue(100);
}
}
I'm trying to implement a basic filtered list box in WPF. The user types something and the list is narrowed to the values beginning with the typed phrase.
I have:
a View with:
a TextBox whose Text property is bound to InstitutionFilteringString property in the ViewModel class, which is set as the data context,
a ListBox whose ItemSource property is bound to an ICollectionView named Institutions in the View Model
a ViewModel class with the properties mentioned above.
Code (with irrelevant parts cut out):
class ChooseInstitiutionAndPublisherPageViewModel : WizardPageViewModelBase
{
private ICollectionView _institutions;
public ICollectionView Institutions
{
get
{
return _institutions;
}
set
{
_institutions = value;
NotifyPropertyChanged("Institutions");
}
}
private string _institutionFilteringString;
public string InstitutionFilteringString
{
get
{
return _institutionFilteringString;
}
set
{
_institutionFilteringString = value;
NotifyPropertyChanged("InstitutionFilteringString");
//WORKAROUND
//Institutions.Filter = new Predicate<object>(FilterInstitutions);
Institutions.Refresh();
}
}
public ChooseInstitiutionAndPublisherPageViewModel(WizardViewModel parent)
: base(parent)
{
Institutions = CollectionViewSource.GetDefaultView(CentralRepository.Instance.GetInstitutions());
Institutions.Filter = new Predicate<object>(FilterInstitutions);
}
private bool FilterInstitutions(object obj)
{
//I may refer directly to the field or through the property, it doesn't change anything
if (_institutionFilteringString == null || _institutionFilteringString.Length == 0)
return true;
//some more filtering, irrelevant
//[cut]
}
}
The view and the binding:
<TextBox Text="{Binding Path=InstitutionFilteringString, Mode=TwoWay}" Height="23" Margin="6,6,87,0" Name="institutionNameTextBox" VerticalAlignment="Top" TextChanged="institutionNameTextBox_TextChanged" />
<ListBox Margin="6,35" Name="institutionsListBox" ItemsSource="{Binding Path=Institutions}" IsSynchronizedWithCurrentItem="True" />
So, to the point. The setter for the InstitutionFilteringString is called correctly. Following an advice from here, the setter calls a Refresh() method on the collection view. The FilterInstitutions() method is called.
And now the bug: even though the string was set just before a second, inside the FilterInstitutions method it's null. If I go with the debugger down the call stack, from the point of view of the setter it's still set to the typed value, but inside the filtering method it's null.
In the setter there is a commented-out line of code. Uncommenting it fixes the bug, but it's hardly how it should be done.
What am I doing wrong?
(I'm not sure, but it seems to me as if the setter and the filtering method operated on two different instances of the class. But how is it possible, I create just one instance and the class is not clonable)
EDIT
I'm sorry, it seems I've lied. I've put a breakpoint in the constructor and it seems I indeed create two instances of the class and CollectionViewSource.GetDefaultView returns the same instance of ICollectionView for both. Well, but I want actually to have two views for the same collection. Well, I've followed this answer and it seems to work :)
do you create your Institutions once? and set the
Institutions.Filter = new Predicate<object>(FilterInstitutions)
once? if yes its ok :) can you post your code for this and also the code for FilterInstitutions methode? i do it all the way in my projects and have no problems.
[This is .Net 3.5.] I have seen a lot of examples that say, do it this way, so I must just be missing something:
I have a project with a Resources.resx file. In the Resources file are Strings that are Public. One of them is "Cancel", shown in this snippet from Resources.Designer.cs:
namespace WFT.PumpSvc.Bench.Properties {
public class Resources {
public static string Cancel {
get {
return ResourceManager.GetString("Cancel", resourceCulture);
}
}
...
Next, I have some xaml that has
xmlns:strings="clr-namespace:WFT.PumpSvc.Bench.Properties"
and
<wft:TouchButton Name="closeButton">"{x:Static strings:Resources.Cancel}"</wft:TouchButton>
(TouchButton inherits from Button.)
Instead of "Cancel" showing on my button, I see {x:Static strings:Resources.Cancel}. Is it obvious what I have missed that isn't finding the string?
You can't write a markup extension directly in an element (at least not in this form), it must be in an attribute:
<wft:TouchButton Name="closeButton" Content="{x:Static strings:Resources.Cancel}"></wft:TouchButton>
You can also write it like this:
<wft:TouchButton Name="closeButton">
<x:Static Member="strings:Resources.Cancel" />
</wft:TouchButton>
You made it a string, it won't be parsed like this, use element-syntax:
<wft:TouchButton Name="closeButton">
<x:Static Member="strings:Resources.Cancel"/>
</wft:TouchButton>
I am having problems getting validation to work properly in the designer for my custom activity. The simplest sample to reproduce the behavior is as follows:
I have a custom WF4 activity with a dynamic collection of arguments stored in a dictionary:
[Designer(typeof(DictionaryActivityDesigner))]
public class DictionaryActivity : NativeActivity
{
[Browsable(false)]
public Dictionary<string, InArgument> Arguments { get; set; }
public InArgument<string> StringArg { get; set; }
public DictionaryActivity()
{
Arguments = new Dictionary<string, InArgument>();
}
protected override void Execute(NativeActivityContext context)
{ }
}
In the designer I dinamically create expression text boxes for editing these arguments. The user has the possibility to define the arguments and their types in a separate modal window, but for the sake of simplicity I have fixed the arguments in this sample:
public partial class DictionaryActivityDesigner
{
private Dictionary<string, Type> definition;
public DictionaryActivityDesigner()
{
definition = new Dictionary<string, Type>
{
{ "String Arg", typeof(string) },
{ "Int Arg", typeof(int) }
};
InitializeComponent();
}
public void InitializeGrid(Dictionary<string, Type> arguments)
{
ArgumentsGrid.RowDefinitions.Clear();
ArgumentsGrid.Children.Clear();
int gridRow = 0;
foreach (var arg in arguments)
{
ArgumentsGrid.RowDefinitions.Add(new RowDefinition());
var label = new Label()
{
Content = arg.Key + ":"
};
Grid.SetRow(label, gridRow);
Grid.SetColumn(label, 0);
ArgumentsGrid.Children.Add(label);
var textbox = new ExpressionTextBox()
{
ExpressionType = arg.Value,
OwnerActivity = ModelItem,
UseLocationExpression = false
};
var binding = new Binding()
{
Mode = BindingMode.TwoWay,
Converter = new ArgumentToExpressionConverter(),
ConverterParameter = "In",
Path = new PropertyPath("ModelItem.Arguments[(0)]", arg.Key)
};
textbox.SetBinding(ExpressionTextBox.ExpressionProperty, binding);
Grid.SetRow(textbox, gridRow);
Grid.SetColumn(textbox, 1);
ArgumentsGrid.Children.Add(textbox);
gridRow++;
}
}
private void ActivityDesigner_Loaded(object sender, RoutedEventArgs e)
{
InitializeGrid(definition);
}
}
Below is the XAML for the designer:
<sap:ActivityDesigner x:Class="ActivityValidation.DictionaryActivityDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapc="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
Loaded="ActivityDesigner_Loaded">
<sap:ActivityDesigner.Resources>
<ResourceDictionary>
<sapc:ArgumentToExpressionConverter x:Key="ArgumentToExpressionConverter" />
</ResourceDictionary>
</sap:ActivityDesigner.Resources>
<StackPanel Orientation="Vertical">
<Grid Name="ArgumentsGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition MinWidth="250" />
</Grid.ColumnDefinitions>
</Grid>
<sapv:ExpressionTextBox ExpressionType="s:String"
OwnerActivity="{Binding ModelItem}"
Expression="{Binding ModelItem.StringArg, Mode=TwoWay, Converter={StaticResource ArgumentToExpressionConverter}, ConverterParameter=In}" />
</StackPanel>
</sap:ActivityDesigner>
The InitializeGrid method adds the expression text boxes for the arguments to the ArgumentGrid. Under it I have a separate statically defined expression text box for a fixed argument in the activity to demonstrate the (almost) desired behavior.
Now for the problems:
Invalid expressions for the dynamic arguments only cause the error icon to appear beside the text box but it doesn't propagate to the top bar of the designer as it does if there is an error in the statically defined text box.
If I close the designer in such invalid state (and save the definition), the eror icon correctly propagates to the top bar even if the error is only in the dynamic text box. Though the behavior gets even more strange afterwards. After changing the values for the arguments, now even the error icon beside the text box doesn't work consistently any more.
If I delete the contents of a dynamic text box completely, the value in the dictionary gets set to null which manifests in the workflow definition as <x:Null x:Key="String Arg" /> instead of <InArgument x:TypeArguments="x:String" x:Key="String Arg">["a"]</InArgument> or just ommiting the entry as is the case before editing the expression for the first time. If I reopen such a workflow even the statically created text box doesn't work properly any more (the error icon is only visible when text box is focused and it doesn't propagate to the top any more).
It seems obvious that I am doing something wrong when creating the dynamic text boxes. What would be the correct way of doing it? Is there any example available for creating a designer for a custom activity with dynamic number of arguments?
EDIT:
For those interested:
There was some more discussion on MSDN Forums where I have also posted the issue.
As a result of that discussion, I've also filed a report on Microsoft Connect.
I encountered the problem I described here while trying to create a designer for a dynamic collection of arguments in an activity. I managed to work around the problem by using the built-in DynamicArgumentDialog window. I had to restructure my activity to accept a single collection of both input and output arguments:
public Dictionary<string, Argument> Arguments { get; set; }
instead of two separate collections I was using before:
public Dictionary<string, InArgument> InArguments { get; set; }
public Dictionary<string, OutArgument> OutArguments { get; set; }
I found the Custom Activity to Invoke XAML Based Child Workflows very helpful when making this work.