The default "split view" template for a Metro application written in C# makes use of an ItemTemplate attribute in the ListView tag. I'm just getting started with XAML and C#, so it's all still a bit overwhelming.
I understand that the ItemsSource is used to provide the data collection to the view, but I'm a bit confused as to how the ListView knows what to display from those model classes. Is this defined by the ItemTemlate? There's a snippet of code:
...ItemTemplate="{StaticResource SnapListItemTemplate}" ItemContainerStyle="{StaticResource SnapListTileStyle}" ItemsPanel="{StaticResource SnapListItemsPanelTemplate}"...
I don't really understand most of that line. Where are these SnapList* options defined? Is there a provided list of available templates, or are these all defined my project somewhere? Does the SnapListItemTemplate look for a specific set of ivars to display? Can this template be altered or "subclassed"?
For example, there are a number of properties on the model classes like title, subtitle, etc. And I'm curious as to how the ListView knows to pull out those specific values, and also how it knows to lay them out. What if I want to change the name of the subtitle ivar to subtext? How is the item template updated?
The SnapList* templates should be defined in your project somewhere.
The binding is {StaticResource ...} which means that the template/style or whatever is usually defined in some XAML file.
If you search the project (Ctrl+Shift+F) for the names they should turn up, probably in a file called Styles.xaml.
Related
I'm working on a solution to a localization problem. This isn't the normal language localisation.
<Label Content="{Binding myDictionary[A Test], FallbackValue=A Test}"/>
In practice the above code calls into the Dictionary in the view model, which is declared as
public Dictionary<string, string> myDictionary
The problem is that I have to define the string "A Test" twice in the label.
once as in the index in the binding, and again in the FallbackValue.
What I would like to end up with is something that looks like this...
<Label Content="{Binding myDictionary[A Test]}"/>
At the moment what happens when I do this is that the Xaml designer in Visual studio can't resolve myDictionary (as it won't know the datacontext so can't hook up to the viewmodel where it's defined) this means that the label will display as blank, which won't will make visual design harder.
I've looked into calling a static method however for myDictionary to function properly, it needs to be instantiated in the view model.
Is there a way of having either the index value "A Test" show up in the designer without having to use a fallback value?
The goal is to be able to have the content refreshed if the value in myDictionary[A Test] is updated (In reality myDictionary is observable)
as it won't know the datacontext so can't hook up to the viewmodel where it's defined
Not so.... One can use a design time only context by specifying it in the page's meta data atttributes such as:
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance {x:Type viewModels:MainVM}}"
by doing that you can setup a design time only dictionary to use.
Read about here in MSDN magazine:
MVVM - Maximizing the Visual Designer’s Usage with Design-Time Data
Note one can still use the Blend namespaces in non Blend editors such as Visual Studio. Otherwise don't be afraid to use/learn Blend as needed.
If from your actual VM with real data, in design mode its good to ignore certain objects/actions which may cause issues. Here is a check to determine if the action is in design mode, if it is not then it executes the block, otherwise it is ignored because it is in design mode.
if (!DesignerProperties.GetIsInDesignMode(this))
Best way to handle this IMO is with a custom markup extension placed within a custom namespace, it allows you to write XAML like this:
<TextBlock Text="{Translate 'Hello World!'} />
What the Translate extension class returns is entirely up to you, typically you have it do a look-up into a Dictionary using the provided string as the index and, if it doesn't find it, just returns the string itself.
One of the nice things about this particular implementation is that it adds a listener to the Translation manager for every binding that is made, so they all automatically update at run-time whenever the current language is changed.
The one thing you do have to keep in mind though is to place the Translate extension class itself within its own project. Not sure why, it seems to be a bug in VS, but XAML files don't seem to be able to use custom markup extensions declared in the same project.
When I'm making a new Visual Studio Windows 8 Store Project (C#), I get dummy data if I start off With a SplitPage, however, if I'm adding new SplitPages to the Project, there's no dummy data coming With it, and I just get a ton of errors if I try the code from the main SplitPage (the one created when I made the actual Project).
How can I get dummy data in the "new added" SplitPages, not only in the main Project file?
You can do it manually. You can use ExampleDataSource classes which you can find in any example.
Then in XAML code, when you describe CollectionViewSource in Page.Resources you usually bind data-source in way like:
<CollectionViewSource
x:Name="itemsViewSource"
Source="{Binding YourDataSource}"/>
Here you use Source parameter to specify binding. Now use parameter d:Source. Namespace d is used for describing things, which will be used only in designer (that's why it is d, I believe).
So try adding this parameter to your CollectionViewSource:
d:Source="{Binding AllGroups, Source={d:DesignInstance Type=data:SampleDataSource, IsDesignTimeCreatable=True}}"
Assuming that SampleDataSource has property AllGroups and it is ObservableCollection, it should work.
Hope my answer helps anyone dealing with Win8 apps.
Answer from Microsoft employee: this is not possible. You'll only get the dummy data if you create the splitpage as the first page within a new project.
I'm trying to implement a multilingual WPF application, I've a problem and I don't know how should I deal with this situation. Let's say I have 2 .Resx files and a TextBlock element which its Text property is bind to a class responsible to translate to a appropriate value by given key. They are work fine in run-time, but working with them is too hard in design-time because they don't able to get values from resources in design-time and Text's values are always empty. I'm curious how can I change Text property of TextBlock element at design-time.
Any advice will be helpful.
you can visit this post
Multilingual WPF application
I have a control that we could identify as similar to ListBox control. Each item is represented with one element (example TextBlock). What i would like is to change the layout of this item, so that it contains two TextBlocks. So I create a ControlTemplate, put a Border Grid, TwoTextBlocks, and all is well. Now the problem:
I need to be able to localize the text in the item, and I did this normally like this:
<... Text="{Binding Strings.SomeString, Source={StaticResource ApplicationResources}}" />
Now I need to be able to do the same with both TextBlocks. So i thought I need to create a custom type that this item will bind to, and expose two propertiws: Title and Description. If I expose this properties as string type, everything works ok, but I am loosing markup binding that I used previously. How to achieve the same with two properties? The result should be like:
<... Title="{Binding Strings.SomeString, Source={StaticResource ApplicationResources}}", Description="{Binding Strings.AnotherString, Source={StaticResource ApplicationResources}}" />
I was able to make Localization work with ResourcemManager class, but it gets even complicated in order to provide localization to be applied dynamically at runtime.
So, what do I need to do to be able to use above code? Then I just need to implement INotifyPropertyChanged on ApplicationResource and all is set.
Great!
I'm going to do the same thing you did here. Yeah, I have a solution but I'm not sure if it works till now.
First, we need a LocalizationManager which holds a dictionary.
For example, if you need to localize a user account window, just do this
<TextBlock Text="something, UsernameKey">
And the localizationManager will map UsernameKey to "Username" or other language
Second, a xaml extension which find the value of the key from LocalizationManager.
I wonder if this custom extension could derived from Binding extension, if so, this'll be very easy, just create a Binding Object to the target. If not, I think holding a WEAK reference to the UIElement by xaml extension to dynamic update the text is proper.
This solution is simple but not generic. There're some language read from right to left. It asks the application to show content from right to left.
So, I have another generic solution but more complex.
Instead of xaml extension, we use an attach dependency property.
Do it like this:
<TextBlock LocalizationManager.LocalizationKey="UsernameKey" />
So, the problem now is how to set "Text" property by LocalizationManager?
We use adapters, LocalizationManager will search proper adapter for type "TextBlock"
So, when the application is booting, we register some adapters to LocalizationManager:
LocalizationManager.Current.RegisterAdapter<TextBlock>(new TextBlockAdapter())
This solution is more generic, it supports any kind of control if you provide adapter, but as you see, this solution needs more work and much more complex than the former one.
I hope these design solutions could help you~
I'm having a WPF Custom Control which represents me a given point on a plan (I'm making a guide application for my studies) and I want it to looks different for different categories of the objects represented by this map node (i.e. toilet, lift or normal room).
Could anyone give me some idea how to do this?
I tried creating a Converter but it didn't goes well.
Also my problem is that sometimes in could be the WPF element like Ellipse and sometimes it should be an image.
Is it somehow possible to create custom control with multiple templates and the template will be selected depending on some category attribute?
For things like this, you might want to have a look at the DataTemplateSelector class. It allows you to select the datatemplate based on the actual object you are binding to.
Here's a tutorial for it, but i'm sure you can find more on the internet:
http://www.switchonthecode.com/tutorials/wpf-tutorial-how-to-use-a-datatemplateselector