Collection declared in XAML hangs Silverlight - silverlight

I have been playing around with declaring objects in XAML. I have these classes in my Silverlight assembly:
public class TextItem
{
public string TheValue { get; set; }
}
public class TextItemCollection
{
public ObservableCollection<TextItem> TextItems { get; set; }
}
Then, I have this in my XAML:
<UserControl.Resources>
<app:TextItemCollection x:Key="TextItemsResource">
<app:TextItemCollection.TextItems>
<app:TextItem TheValue="Hello world I am one of the text values"/>
<app:TextItem TheValue="And I am another one of those text items"/>
<app:TextItem TheValue="And I am yet a third!"/>
</app:TextItemCollection.TextItems>
</app:TextItemCollection>
</UserControl.Resources>
For some reason if I include that node when I try to debug the application, Silverlight hangs (I just see the spinning blue loading circle thingy). If I comment out that node, it runs immediately.
Any ideas?

By code review: Your TextItems property is null. That can't help the XAML parser.
By experimental results: I get an exception when running the app in the debugger (I'm using Silverlight 4):
System.Windows.Markup.XamlParseException occurred
Message=Collection property '__implicit_items' is null. [Line: 12 Position: 40]
LineNumber=12
LinePosition=40
StackTrace:
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
InnerException:
You should initialize TextItems. You should also make the setter private so others can't mess you up. Try this, you should find it works fine:
public class TextItemCollection
{
public TextItemCollection()
{
TextItems = new ObservableCollection<TextItem>();
}
public ObservableCollection<TextItem> TextItems { get; private set; }
}

Related

The IRequestNavigationService is not being instantiated

In a program that was working, I started getting the following exception:
Activation error occurred while trying to get instance of type IRegionNavigationService
The inner exception is
InnerException {"The current type, CommonServiceLocator.IServiceLocator, is an interface and cannot be constructed. Are you missing a type mapping?"} System.Exception {System.InvalidOperationException}
Since this is part of the Prism 6 platform, I'm at a loss as to where to start to fix the problem.
The problem started when I was updating the project from a repository and the solution file became corrupted. I got the program to run, but when I choose an option that navigates to another view I get the exception.
Here is the code that gets the exception:
public class MainMenuViewModel : BindableBase, IRegionManagerAware
{
public IRegionManager RegionManager { get; set; }
public MainMenuViewModel()
{
CustomerProfileCommand = new DelegateCommand(ExecuteCustomerProfileCommand);
AdjustmentTypeCommand = new DelegateCommand(ExecuteAdjustmentTypeCommand);
StreetProfileCommand = new DelegateCommand(ExecuteStreetProfileCommand);
LocationMaintenanceCommand = new DelegateCommand(ExecuteLocationMaintenanceCommand);
}
private void ExecuteLocationMaintenanceCommand()
{
RegionManager.RequestNavigate(RegionNames.ContentRegion, NavigationNames.LocationMaintenance);
}
private void ExecuteStreetProfileCommand()
{
RegionManager.RequestNavigate(RegionNames.ContentRegion, NavigationNames.StreetMaintenance);
}
private void ExecuteAdjustmentTypeCommand()
{
RegionManager.RequestNavigate(RegionNames.ContentRegion, NavigationNames.AdjustmentTypeMaintenance);
}
private void ExecuteCustomerProfileCommand()
{
RegionManager.RequestNavigate(RegionNames.ContentRegion, NavigationNames.CustomerProfile);
}
public ICommand CustomerProfileCommand { get; set; }
public ICommand AdjustmentTypeCommand { get; set; }
public ICommand StreetProfileCommand { get; set; }
public ICommand LocationMaintenanceCommand { get; set; }
}
The RegionManager is instantiated by a region behavior and (using debug to verify) is actually instantiated.
Any direction as to where I should start is appreciated.
OK, I found the problem. I had upgraded the CommonServiceLocator package to 2.03. Apparently, Prism 6.30 only works with version 1.3.0. After I made that change, the program worked.

Getting most basic MetaDataType to work

In addition to my original post I guess I need to mention that I am using Prism 6.3. Apparently, the compiler doesn't like stuff added to the metadata class that's not in the original partial. Not sure how to resolve this.
Thanks again ... Ed
Ok, I give, UNCLE!
I am trying to add data annotations to my wpf entity framework app. I've tried 6 ways to Sunday with no luck. I put together what is what I consider the most simple example possible and followed all the instructions ... nothing works.
Here goes.
I have a class that is generated by EF (db first).
namespace junk.DataModels
{
public partial class MyClass
{
public string SomeText { get; set; }
}
}
I have another file with the following partial class:
namespace junk.DataModels
{
[MetadataType(typeof(MyClassMetaData))]
public partial class MyClass
{
}
public partial class MyClassMetaData
{
private string _someText;
[Required(ErrorMessage = "Required")]
public string SomeText
{
get { return _someText; }
set { SetProperty(ref _someText, value); }
}
}
}
In my ViewModel I define:
private MyClass _mc;
public MyClass MC
{
get { return _mc; }
set
{
SetProperty(ref _mc, value);
}
}
And in the constructor:
MC = new MC();
MC.SomeText = "Hello World.";
Lastly, in my xaml:
I have a single bound control:
<TextBox x:Name="txt" Text="{Binding MC.SomeText,
ValidatesOnDataErrors=True,
ValidatesOnExceptions=True,
ValidatesOnNotifyDataErrors=True,
UpdateSourceTrigger=PropertyChanged }"
/>
According to everything I've read, if I run this and clear the textbox, I should get a validation error. I have tried all combinations of "ValidatesOn" it doesn't seem to make a difference. Can someone take pity on me and share the secret sauce? I must be missing something simple. If I bind to the metadataclass it works but that is kinda defeating the purpose.
Any help would be great!
Try adding the following static constructor to your buddy class "MyClass". It will register the metadata against your EF class so the Validator can find the Data Annotations:
static MyClass()
{
// Register the metadata against our EF data object.
// This will ensure the Validator find the annotations
TypeDescriptor.AddProviderTransparent(
new AssociatedMetadataTypeTypeDescriptionProvider(
typeof(MyClass),
typeof(MyClassMetaData)),
typeof(MyClass)
);
}
You could also try running a unit test to confirm whether the Validator has used your annotation, before adding the complexity of the GUI:
[TestMethod]
public void TestAnnotations()
{
MyClass c = new MyClass();
// Manually validate the MyClass object
List<ValidationResult> validationResults = new List<ValidationResult>();
ValidationContext context = new ValidationContext(c, serviceProvider: null, items: null);
bool isValid = Validator.TryValidateObject(c, context, validationResults, validateAllProperties: true);
Assert.IsFalse(isValid, "Validation should fail because we didn't set SomeText");
}

XAML collection of interface/abstract "Could not create an instance"

I have in the ViewModel an ObservableCollection<INode> where INode is an interface.
The View XAML is like:
<Windows x:Class="XXX.Window1"
xmlns:vw="clr-namespace:XXX.Views"
xmlns:vm="clr-namespace:XXX.ViewModels"
xmlns:n="clr-namespace:XXX.Models.Nodes"
... />
...
<vm:MyView>
<vw:MyView.DataContext>
<vm:MyViewModel>
<vm:ComponentViewModel.Nodes>
<n:MyNode /> <--- PROBLEM HERE
<n:MyNode />
</vm:ComponentViewModel.Nodes>
</vm:MyViewModel>
</vw:MyView.DataContext>
</vm:MyView>
...
Now this works at runtime, but not in the design time window which shows:
Could not create an instance of type 'MyNode'
Any idea how to solve this?
interface INode
{
string Name { get; set; }
string Status { get; }
}
abstract class Node : INode
{
public string Name { get; set; }
public abstract string Status { get; }
public override int GetHashCode()
{
unchecked
{
return Name.GetHashCode(); // <--- PROBLEM WAS HERE, Name = null
}
}
}
class MyNode : Node
{
public override NodeStatus Status { get { return "test"; } }
}
Each case seem to be unique. Here's what I learned after solving it: Not only an exception in the constructor can generate that error message. If some system methods like GetHashCode() throw and exception, it'll display that same message (some times at design-time only).
Other people may have more tips or more insight VS design-time flow.
As far as I can see it is not a XAML problem, but happens because you are not setting the Name property. When GetHashCode is called it will fail because you are calling a method on a null reference.
Try adding your node as
<n:MyNode Name="blah" />

EF 4.1 Codefirst WPF Eager Loading Data Binding

I am having problems databinding to EF code first. I need to be using Eager Loading, but I am running into some issues with databinding. I have the following classes:
public class Context : DbContext
{
DbSet<A> As;
DbSet<B> Bs;
DbSet<C> Cs;
}
public class A
{
public ICollection<B> Bs { get; set; }
public string Name { get; set; }
}
public class B
{
public ICollection<C> Cs { get; set; }
public string Name { get; set; }
}
public class C
{
public string Name { get; set; }
}
I am data binding Context.As to a Treeview, using the below code:
Context.As.Load();
tvItems.ItemsSource = Context.As.Local;
This works as expected, however, it does not automatically load the child properties, Bs, and subsequently, Cs. So, I found that lazy loading can help with this, like so:
Context.As.Load();
tvItems.ItemsSource = Context.As.Include(u=>u.Bs);
From my reading, this should automatically load at least the first level of child properties. However, this will not data bind, as I did not use .Local
.Include() returns IQueryable, which does not support .Local. I can use .ToList(), but this will not automatically update when I add items.
So, how the hell am I supposed to be doing this?
You could try this:
Context.As.Include(a => a.Bs).Load();
tvItems.ItemsSource = Context.As.Local;

Cinch version of ViewModel command to close a View

Without wanting to bug sacha too much, does anyone know what the Cinch V2 way of closing a View from a ViewModel command?
Previously I have used a RelayCommand in the ViewModel base to accept the Escape keybinding command action and wired up a RequestClose event in the View code behind to do this.
Use CloseActivePopUpCommand.Execute(true) in the execute method to close a view.
I've included a short sample below.
[ExportViewModel("PickOperatorViewModel")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class PickOperatorViewModel : ViewModelBase
{
[ImportingConstructor]
public PickOperatorViewModel()
{
PickOperaterCommand = new SimpleCommand<Object, Object>(CanExecutePickOperaterCommand, ExecutePickOperaterCommand);
}
public SimpleCommand<Object, Object> PickOperaterCommand { get; private set; }
private void ExecutePickOperaterCommand(Object args)
{
CloseActivePopUpCommand.Execute(true);
}
private bool CanExecutePickOperaterCommand(Object args)
{
return true;
}
}

Resources