Let me preface this by saying, I'm not sure if this is even possible. I've got two similar collections of complex objects that I'm using as source data for two different Items controls. Well, let's call the first collection the old data, and let's call the second collection the new data.
Like I said above, I've got two items controls - one binding to old, and the other binding to new. Well, in the item template of the new items control, I want to be able to bind to the old data, however I need to be able to use an index because the property is List of items. Maybe code snippets will help explain what I'm after:
<ItemsControl.ItemTemplate>
<DataTemplate>
<Textblock Text="{Binding Path=OldSourceData.MyList[0]}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
However, I need to replace 0 with the alternation index of the current item. I'm using this to get the correct index {Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource TemplatedParent}}
How do I replace 0 with the alternation index?
EDIT
I'm trying to figure out how to do something like this: <Textblock Text="{Binding Path=OldSourceData.MyList[{Binding Path=(ItemsControl.AlternationIndex), RelativeSource={RelativeSource TemplatedParent}}]}"/> Obviously, this syntax doesn't work, however is it possible to accomplish this somehow?
Related
<press_limits value="1055" label="Press Limits" type="single 317" format="object">
<projected_area value="0.052944637336319995" label="Projected area of part" type="real(m*m)"/>
<press_tonnage value="500.0" label="Press tonnage" type="real(g)" units="0Ton"/>
<within_press_limit value="1" label="within limits of press" type="boolean"/>
From XML like the above, the XAML below will generate a form that displays the values, with appropriate controls and value formats. But I can't get the stuff converted back. I fail to see a simple change that will meet the requirements of Binding. Perhaps fixing this requires an architecture change. How can I do this differently?
The magic starts here. Bind this ItemsControl to an XmlElement, and it builds a ControlChooser for each subelement.
<ItemsControl ItemsSource="{Binding XPath=*}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate><WrapPanel/></ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<W3V:ControlChooser Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The ControlChooser triggers on the format attribute:
<Style.Triggers>
<DataTrigger Binding="{Binding XPath=#format}" Value="spin">
<Setter Property="ContentTemplate" Value="{StaticResource combo}" />
</DataTrigger>
to pick a DataTemplate:
<DataTemplate x:Key="combo" > <W3V:ComboView /> </DataTemplate>
which instatiates the following control:
<ComboBox Style="{StaticResource ComboButtonStyle}" Width="200"
Text="{Binding Path=., ## PROBLEM, BUT HOW TO AVOID?
Converter={StaticResource valueFormattingConverter },
IsEditable="True" />
valueFormattingConverter uses the #units, #type, and #value attributes to produce properly formatted text. The trouble is, this doesn't convert back. I asked here: TextBox ConvertBack event doesn't fire for XML element, and learned that it is impossible for Path=. to be used as '.' is an object but not a dependency property.
So then, I need a way to provide a DependencyProperty for Binding. So ComboView needs to receive an object that has a property which is or has the XmlElement I want. I think this means I really need to change things around but haven't the slightest idea how. Maybe there's an MVVM approach to doing this??? Any insights will be appreciated.
An upcoming issue is a need to validate the data typed in and process the information.
The MVVM method: pull the data out of the XML file, and put it a class which is the ViewModel. Each property in the ViewModel corresponds to an item of data in the XML file. Then use a custom DataTemplate to render the contents of the ViewModel to the screen.
We can extend this to render a list of items. Each item in the list is a ViewModel. A DataTemplate always renders based on the type of the property it is attached to. So you can have a list of objects, and a custom DataTemplate for each item in the list. Of course, all of the items in the list would have to inherit from the same type.
This means you can have a list of items, and each item can render differently depending on the type of data in the XML file. This means that each item in the list can have a custom look and feel with different number of decimal places, colors, etc.
I've used this technique before, and it works well.
Update
For examples, see:
http://www.wpftutorial.net/datatemplates.html
http://www.stackoverflow.com/questions/3400532/display-multiple-types-from-a-single-list-in-a-wpf-listbox.
If I was solving this, I would look at generating C# on the fly. Here is how I would do it:
All XAML compiles to a series of C# commands.
I would set the XAML to format things the way I like it.
I would find the equivalent C# code.
I would then insert the appropriate if/else statements to alter the C# to suit.
Another method that I would try:
Its possible to render custom XAML into an area on the screen.
I would edit the XAML, based on the XML, then display this custom XAML on the screen.
I'd be curious to know if either of these methods work in practice, or if there is a better method that would work.
I had the following XAML looking just as I want it to look. It's basically a dropdown menu with checkboxes and some text to them.
<ComboBox x:Name="comboBox">
<ComboBoxItem><CheckBox>WeeHee</CheckBox></ComboBoxItem>
<ComboBoxItem><CheckBox>BuuHuu</CheckBox></ComboBoxItem>
</ComboBox>
Then I learned that the options are possible to be dynamically adapted so I changed the markup and bound the combobox to an array. That works perfectly well functionality-wise but now I get only the names of the options, while the checkboxes are gone.
<ComboBox x:Name="comboBox"
ItemsSource="{x:Static local:MainWindow.AllKinds}">
</ComboBox>
So I'm looking for a way to create a custom item for populating the combobox but still so that the data is dynamically bound. I'm assuming WPF/XAML supports such functionality and I'm just too ignorant to know what to google for.
So my request is a rudimentary example or suggestion on what to google for. (Might be something seemingly obvious to everybody but me.)
So with most of the controls that offer up things from ItemSource there's a nifty built in feature that allows you to specify how each item should look/behave etc. So you can specify each Item in your ComboBox's by setting your own ItemTemplate.
Since a ComboBox just uses an ItemsControl to list its items, you can utilize this via ComboBox.ItemTemplate to make your items however you like, in this case probably something like (in pseudo).
<ComboBox>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Hope this helps, its some pretty handy info to know for when you want to start customizing Item generated lists between wpf, silverlight, wp, win-rt, etc. Cheers!
I want to create a ListBox and fill it with anonymous UIElement. In other words, the DataTemplate of the ItemTemplate will contain only one element, and afterwords during the runtime, afterwards I will create in the code behind different UIElements (TextBlocks, Grids ...) and populate the list with it.
So how am I going to write the DataTemplate of the ListBox? And how am I intend to use an ObservableCollection for the ItemSource? So should use an ObsevableCollection of UIElement?
First Question: No DataTemplate. Since your items are already UIElements, you don't need a DataTemplate.
And if you're creating a changeable collection, then yes, ObservableCollection<UIElement> is the way to go.
Now, why would you be doing this? You may want to ask yourself if this is the best way of doing things. Why isn't your data and your presentation separated? If you need more than one type of element in the list, will DataTemplateSelector allow you to have a real ViewModel?
<ListBox x:Name="name" ItemsSource="{Binding source}">
<ListBox.ItemTemplate>
<DataTemplate>
<textbox x:Name="name"></ToggleButton> //or any tool
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I need to bind the listbox with list of items retreived from database. Each list item is displayed as checkbox in listbox.
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
Along with the checkbox, I also need to add a checkbox as a list item.
Could anyone let me know as to how this can be done?
DataTemplateSelector options within WPF this allow a very small amount of backend code to take care of all the selections for you. This allows you to make use of this code from within an MVVM structure without any issues, and while making the front end extremely easy to manage without complicating the back end code.
here is a sample.
Use DataTemplateSelector if you want to use two different visuals as list items.
Here's the problem: I have a data-bound list of items, basically a way for users to map a request to a response. The response is an xml-based file. I'm letting them queue these up, so I've used a combobox for responses. The responses will include the full path, so they get a bit long. I want the displayed text of the combobox to be right-justified so the user can see the file name. For my static controls, I just use ScrollToHorizontalOffset() when a file is loaded and I'm done. For this dynamic list, I'd like to do it in xaml.
The "somewhat ugly" solution would be to store all the ComboBox objects as they load... then I can call ScrollToHorizontalOffset() directly, but I'd really prefer to do it a cleaner way than that! EDIT: (Actually, this may not be reasonable. A quick look at trying to hack around this issue gets into some really awkward situations trying to map my datasource items to the controls)
I've tried HorizontalContentAlignment, that only impacts the "dropped-down" portion of the ComboBox.
I've also tried to hook other various loading events, but haven't found one that works.
Using an Item template you can decide what will be shown.
You can set tooltip. You can then also use converters to add the dots.
<ComboBox x:Name="ConfigurationComboBox" VerticalContentAlignment="Center" ToolTip="saved configuration" SelectionChanged="ConfigurationComboBox_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate >
<StackPanel>
<TextBlock Text="{Binding}" ToolTip="{Binding Path}"></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
To measure the text, see Measuring text in WPF.