is it possible to write something like this in XAML:
<DataTemplate DataType="{x:Type vm:EntityListViewModel<T>}">
BUT
I need to specify generics because the declaration is EntityListViewModel<T>.
May be use DataTemplateSelector.
There are some support for generics in xaml 2009
http://blogs.windowsclient.net/rob_relyea/archive/2009/06/01/xaml-using-generic-types-in-xaml-2009.aspx
But im not sure if that works with datatemplate.
You could however experiment with setting the DataType property from code... i havet tried that though :)
Related
So i have a simple question; I want to display the System.Windows.Visibility Enum in a ComboBox. However i don't seem to find the path to it. Searched like a crazy man but couldn't find anyone who know the path to this enum.
I'm aware that this can be done in code (and already have it working) but i prefer to do it in XAML.
Could anyone help me out?
Voila:
<ComboBox SelectedIndex="0">
<Visibility>Visible</Visibility>
<Visibility>Collapsed</Visibility>
<Visibility>Hidden</Visibility>
</ComboBox>
No additional namespaces needed.
#Maciek's solution is the simplest and quickest to apply, however more general, pure XAML way of listing enum values is this:
<FrameworkElement.Resources>
<ObjectDataProvider x:Key="ItemsSource"
ObjectType="{x:Type sys:Enum}"
MethodName="GetValues"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="Visibility" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</FrameworkElement.Resources>
(...)
<ComboBox ItemsSource="{Binding Source={StaticResource ItemsSource}}" />
You can then simply replace Visibility with any other enum type to get a list of its values.
If you want to bind enum values to ItemsSource, you need a property in ViewModel with enum values. Than you have to bind ItemsSource to this property. You get values of enum like this:
Enum.GetValues(typeof(EffectStyle)).Cast<EffectStyle>();
If you can't find a path to your property, that means you have wrong DataContext. Set it to your ViewModel class or to your window, if your are not using MVVM. In the simplest scenario, you could set DataContext to your window in Window constructor.
this.DataContext = this;
Take a look at this or this link, as a big picture of DataContext and Binding in WPF.
If you are interested, also read about MVVM in WPF. You could use MVVM Light
If you want a fully xaml solution for your enum binding to ComboBox, you could write sth like this or use ObjectDataProvider like here.
I think Maciek's solution is good enough in your case.
If you want to do it using code, let's say your combobx has an x:name = my combo you can simply do:
mycombo.ItemsSource = Enum.GetValues(typeof(Visibility)).Cast<Visibility>();
I would like to use a TemplateSelector to select a View. Not for ListViewItems, like every example out there shows, but with a "normal" View. So i tried TemplatedView, ContentPresenter and ContentView. But non of them is able to take a TemplateSelector.
Is there something i have missed? Or how can i work around that?
EDIT:
I have a TemplateSelector, just like described here. Now i want to add this Selector to some kind of ViewElement. Thats what i tried:
<TemplatedView ControlTemplate="{StaticResource ViewItemTemplateSelector}"/>
or
<ContentPresenter Content="{StaticResource ViewItemTemplateSelector}"/>
But nothing works, it always says "Invalid resource type"
EDIT2:
<ResourceDictionary MergedWith="dataTemplates:DataTemplates">
<helper:ViewItemTemplateSelector x:Key="ViewItemTemplateSelector"
TextDataTemplate="{StaticResource TextDataTemplate}"/>
Have you tried following this guide of Xamarin?
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/templates/data-templates/selector/
Hope this works out for you.
EDIT:
Perhaps an alternative solution:
There are control templates but i don't think there is a selector for it. You could maybe use triggers for it? https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/triggers/#Data_Triggers not sure if this is way you looking
For example, I'd like to do something similar to what you see below, but in code behind. I see tons of example using XAML, but nothing for doing the same thing in C#. So my guess is no. Thanks.
<Window x:Class="WpfApplication1.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">
<StackPanel>
<TextBlock TextWrapping="Wrap" Width="455">
<Span FontSize="20">2</Span>
<Span BaselineAlignment="TextTop" FontSize="14">1/2</Span>
<Span FontSize="20"> + </Span>
<Span FontSize="20">3</Span>
<Span BaselineAlignment="TextTop" FontSize="14">3/4</Span>
<Span FontSize="20"> = </Span>
<Span FontSize="20">6</Span>
<Span BaselineAlignment="TextTop" FontSize="14">1/4</Span>
</TextBlock>
</StackPanel>
Yes, this XAML output can be done through C# code as well
Pseudocode
Create a StackPanel object
Create a TextBlock object. Set it's TextWrapping Property to Wrap and Width to 455.
Create multiple objects of Span. Set the FontSize and other properties (text, BaseAllighnemt) according to your needs.
Addspan objects to Textblock.Inlines property
Add Textblock to stackpanel
Thats it
Actually, almost anything that can be done in Xaml can be done in C# as well, since Xaml is converted into C# when building (look for *.g.cs files). You mostly can just use the same classes you specify in the Xaml, with a few additions that Xaml handles automatically for you. In this case you can do:
var textblock = new TextBlock();
textblock.Inlines.Add(new Run("2") {FontSize = 20});
textblock.Inlines.Add(new Run("1/2") {FontSize = 14, BaselineAlignment = BaselineAlignment.TextTop});
The XAML code is parsed and objects are created that correspond to the markup, so you can always do the same by creating the objects directly.
So, you just create Span objects and set the right properties, and add them as children to a TextBlock object.
For the XAML you posted, believe me, the XAML is much more readable and compact. For you to do this in code, you would have to instantiate the Window and the StackPanel, add the StackPanel to the Window, give the Window its title, height, and width properties, etc, etc. You're already looking at about six lines to do just that, it gets even uglier when you start instantiating the TextBlock and setting the Span.
You can absolutely use WPF without the XAML, although I'm not really sure why you would ever want to. An example of a WPF program that does just that can be found here. In fact, the reverse of your question is true. Everything you can do in XAML, you can do in C#, but not everything you can do in C#, you can do in XAML. This is because XAML maps directly do Common Runtime Language classes, properties, events, etc. but a mapping doesn't exist between every class and a piece of XAML code.
Long story short, XAML is much more maintainable and easier to edit than pure code, and requires simpler tools (an XML editor) to work with and is thus preferable to using pure code.
In Silverlight (or WPF for that matter) you can something like this:
<UserControl ...>
<UserControl.Resources>
<DataTemplate x:Key="SomeKey">...</DataTemplate>
<DataTemplate x:Key="AnotherKey">...</DataTemplate>
<DataTemplate x:Key="OneMoreKey">...</DataTemplate>
<UserControl.Resources>
...
Now when I have my own custom control which takes a collection of DataTemplates.
I cannot set x:Key on those DataTemplates, why not? (first question!)
Now I think it has something to do that my collection does not inherit from ResourceDictionary.
If that is the answer HOW do I create an attached property which can only be set on Children (DataTemplates) of my own custom control?
I found AttachedPropertyBrowsableForType but I cannot find it for Silverlight...
You are correct that x:Key is for Resources.
What is this attached property for? You might be going about it the wrong way.
So you've got a usercontrol. You would like to bind to some of its dependency properties, so you need specify an x:Name in order to use it.
You can't do this...
<UserControl x:Class="WpfApplication1.UserControl1" x:Name="UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid />
</UserControl>
...because member names cannot be the same as their enclosing type.
So you need to pick something else... but what's a good convention to go for here? Stick something arbitrary on to the end? "UserControl1UserControl"? Call it "Root"? Use a different case "userControl1"?
What choices have you guys been making?
I know this is really minor, but I try to name elements very carefully and consistency is important to me.
Name it however you named the XAML file.
Foo.xaml:
<UserControl x:Name="foo" ...
Be descriptive; be consistent.
In other words, just pick something and stick to it.
These names end up as fields in your class, so I just use standard field naming conventions. And if it's the root-level control, I always call it "_root":
<UserControl x:Name="_root">
<StackPanel>
<TextBox x:Name="_nameTextBox"/>
<TextBox x:Name="_ageTextBox"/>
</StackPanel>
</UserControl>