I am globalizing my WinRT app and I can't use language resources in my comboboxs. I can use it in my TextBlocks using Text property but not using x:string. What am I doing wrong?
TextBlock x:Uid="Priority" Text="Default"></TextBlock>
<ComboBox>
<x:String x:Uid="Color">Default1</x:String>
<x:String x:Uid="Color.Text">Default2</x:String>
</ComboBox>
EDIT
Why can't I populate ComboBox elements with resource strings in XAML code? I know that I can add TextBlock elements inside ComboBox to use dictionaries or, as I am doing now, load them through code but this is not the response to my question.
As far as I know when you use in xaml that is a compile time constant which will not be able to change at runtime and bind to a resource. That is why you probably see Default1 or Default2 as items in your combobox.
I was able to find a solution to your problem.
The idea is that in the combobox you should use ComboBoxItem and set the x:Uid to the value of the resource. But in the resource file, the actual name should be Name.Content, because ComboBoxItem has a ContentPresenter in it as default and not a TextBlock.
So this is the code that worked for me:
In the resource file I have:
Combo.Content ComboBox1
And in the Xaml I used:
<ComboBox>
<ComboBoxItem x:Uid="Combo" />
</ComboBox>
This will populate the ComboBox with an item "ComboBox1" (from the resource file).
I have not tested this to see if it works with resource files for different languages, but I see no reason why it should not work.
I would suspect (but haven't found specific statement in documentation), that the entries in resource.resw would need to be (dependency?) properties of the objects for the automatic resource binding to work. Strings don't have such properties; Default1 isn't a value for String.Content, for example.
Path of least resistance would be using TextBlock for you ComboBox elements. Alternatively, you could load the resource in code and assign it to the string that way.
Is there anything preventing you from using a binding for the ComboBox's ItemsSource? That way you could use a custom object that contains the information you need, as well as a DisplayName property, which can then get the correct resource string from the .resx file.
If that's not an option at all, I'm not sure right now what the solution would be to do the whole thing entirely in XAML.
Related
Okay so in wpf xaml markup the data binding features allow for data binding a list to a listView. To do I specified the DataContext and set the ItemSource to the DataContext. This works and the listView is populated with the items. The items though are objects and to be able to have the displayed item in the list view as a string property of get set implementation from the object enumerated in the list view I am attempting to use an Item Template. Though this is not working and I'm uncertain why.
How exactly does Item Template and the Data Binding function in this scenario? And what would be workable solutions to this problem? Is there a way to specify the property in the text box as being local to the enumerated objects. Please Help I've honestly been working on this for a while and research hasn't provided the answers.
ItemList is a list of objects. ItemName is a string property of ItemList. The ItemSource and DataContext works but the textblock does not.
Preferably a solution using only xaml.
<ListView DataContext="this.ItemList" ItemsSource="{Binding }" Name ="Items">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding ItemName}" >
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
Except for some unconventional ways of working pointed out by Clemens, I think the only actual error you make is the fact that ItemName is a property of ItemList instead of the enumerated objects' class.
You ask "Is there a way to specify the property in the text box as being local to the enumerated objects". Well, this is the actual case: the TextBlock's datacontext IS the enumerated object. More precisely: all bindings in the itemtemplate will go look in the enumerated object unless the binding explicitly tells otherwise. So, if your enumerated object has eg. a string property ObjectName, its value will definitely get bound and shown by the textblock.
I was wandering if someone can explain to me how the Dependency Property DisplayMemberPath works?
I am trying to create Custom ItemsControl that has property like DisplayMemberPath of a ComboBox, in otherwords after setting the ItemsSource I want to be able to specify the Property to Display.
At the moment if I do somthing like:
<cc:MyControl ... DisplayMemberPath="MyObjectDescription" ... >
(Yes I have overridden the DisplayMemberPath, its besides the point).
It displays a list of items, but they each Display "MyObjectDescription", instead of the value that that Property holds for each object in the ItemsSource.
And I believe its because I am missing something in regards to how DisplayMemberPath Property works.
Thanks All. :)
There are two types of DisplayMemberPath. One that supports Binding and one where you have to set a string value. In your case as I can see you wish to implement the second one. To do so create a property inside your custom control of type string and name it DisplayMemberPath. Override the methode OnInitialized in your container with your custom logic where you tell the container to manipulate the path of the binding to DataContext by changing binding's path to the string value as you specified in DisplayMemeberPath. WPF calls OnInitalized once any control is completely initalized but before its about to get rendered. I hope this helps you any futher.
I'm assuming your control is like MyControl and MyControlItem like ListBox and ListBoxItem.
You can access the DisplayMemberPath of MyControl when the MyControlItem is being created and use it to get the data from the DataContext.
Bit late to party, but maybe other could be helped
If your purpose is barely to use Itemscontrol over ListBox/View, you may consider to define the Datatemplate for the itemscontrol's Items instead of packing this in a Usercontrol:
<ItemsControl ItemsSource="{Binding myObjectCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding myObjectProp}"/> (or whatever...)
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I may be making this more complicated than necessary ... but here goes.
I have my MainPage.xaml, in there I have references to two other UserControl's, ResultsView, and DetailsView.
Inside of the ResultsView, I have a ListBox bound to an ObservableCollection of custom items, I have a DataTemplate that is rendering each item. The item has a CaseID, and when I click on it, it's displayed as a HyperlinkButton, I need a Command I've set in the MainPageViewModel to fire, which handles changing the visibility to hide the ResultsView, and show the DetailsView.
How do I bind the Command of the Hyperlinkbutton to the Command located in my MainPageViewModel?
Thanks in advance!
edit for clarification:
MainPage.xaml
<resultsView:ResultsView/>
<detailsView:DetailsView/>
Each of the two views (ResultsView & DetailsView) have their own ViewModel. So I'm going from my DataTemplate which resides in a ListBox inside my ResultsView, I need to go up to the MainPageViewModel, an extra step than your answer mentioned. Tried your method naming my MainPage.xaml to Name="mainPage", and using that as the ElementName in my HyperlinkButton, but no luck. I'll do some research on the RelativeSource option and see if I can make that work.
Thanks for your help so far.
edit 2: Forgot to add that the DataTemplate is in a ResourceDictionary, not in the ResultsView.
Well, it depends on the specific details, not all of which you've told us, but I can give you some examples.
Let's say that your DataTemplate for the custom items resides in the XAML of the ResultsView user control. That's a good spot for it but you might have put it in a resource dictionary.
As you say, the ListBox is bound to the collection of custom items. Let's further assume that the custom items collection is itself a property in your MainPageViewModel. And you've said clearly that the command you want to bind to is also in MainPageViewModel.
So the problem, which is a very common one, is that you are working inside a template associated with a binding to a collection, and so your DataContext is a custom item. It is no longer the main view-model itself. That's great as you show appropriate properties of the custom item like CaseID. But it's not great when you want to escape to the top-level of view-model.
If what I've said is true, then the ResultsView user control is in fact probably bound to the MainPageViewModel because you haven't "drilled into" the custom items collection yet. So, what you need to do is find a way using the binding syntax to reference the ResultsView user control from inside the DataTemplate for the ListBox. If you can do that, then you've escaped the collection.
There are two main approaches to do this:
ElementName syntax
RelativeSource syntax
I'll describe ElementName syntax and you can look up the other one.
Part 1) Name your ResultsView UserControl element like this:
<UserControl ....
Name="resultsView">
<!-- ... -->
Part 2) Inside your DataTemplate where you are defining the appearance of the hyperlink use the ElementName syntax to refer to that element:
<TextBlock>
<Hyperlink Command="{Binding DataContext.ItemDetailsCommand, ElementName=resultsView}"/>
</TextBlock>
So first we use ElementName to get the ResultsView UserControl element, and then we have a path with two pieces: the first piece is the DataContext property of the ResultsView which gives us the MainPageViewModel (yeah!), and then the property of the command we want to invoke.
That's one way to "escape" the binding and issue commands found at a higher level in the view-model.
I have observed a strange behavior, I have a XAML Combobox (SilverLight4) declaration with bound SelectedItem and ItemsSource and it appears that the order of SelectedItem and ItemsSource does matter... If SelectedItem is 2nd the control doesn't init properly (nothing is selected), if it was code I can understand why it matter because you can't select item which is not in combobox items collection, but this is XAML...
Do I understand it right that XAML attributes order influences generated code line order? Or it's just something wrong with my code?
That's right - check the answers here: Silverlight XAML Attribute Definition Order Matters, it's due to the XAML being used to create the objects.
I have little problem with databinding in my current project.
I have an ObservableCollection I want to bind to an ListBox.
public ObservableCollection<GeoDataContainer> geoList = new ObservableCollection<GeoDataContainer>();
...later...
geoListBox.ItemsSource = geoList;
This code works fine. The Listbox has a datatemplate and everything looks perfect.
But I don't want to use C# code for binding. I want to make the binding in the XAML Code.
I am searching for days but I don't get it. These are two lines C# code but to archive this in XAML it seems impossible without creating my own class for my collection or adding a DataProvider or resources or whatever.
Is there no easy way to do it?
All you have to do is expose the collection and bind to it. For example, if you expose it as:
public ICollection<GeoDataContainer> GeoList
{
get { return geoList; }
}
You will be able to bind to it as:
<ListBox ItemsSource="{Binding GeoList}"/>
The "trick" is to make sure that the DataContext of the ListBox is the class that exposes the GeoList property.
Another good way would be instantiating geoList as a resource
<WindowResources>
<l:GeoCollection x:Key="geoList"/>
</WindowResources>
Then you have
GeoCollection geoList = FindResource("geoList") as GeoCollection;
Of course, this is for cases when the data is related to the view only. If this is related to model or modelview, you use DataContext and bind to its properties.
Kent suggestion is the way to go...
On a further note, if you do not wish to set your DataContext to the list, you can also retrieve the property with an another form of binding:
Make sure your root control has a name, i.e. "Root"
{Binding ElementName=Root, Path=GeoList}