Custom Item Template for ComboBox Items - c#

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!

Related

WPF/ItemsControl How to Bind to Index of Another Collection Using AlternationIndex

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?

ListBox of anonymous UIElements

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>

how to add two different controls (checkbox and combobox) as list item in ListBox wpf

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.

View / Edit dynamic parameters in a grid

I'm evaluating the possibilities to view and edit parameters in a C#/WPF/MVVM application. I'm currently looking into some custom controls from WPF Woolkit Extended, Telerik, DevExpress and Syncfusion. I see two options, a PropertyGrid or a DataGrid-like control.
The problem: My parameter content is in a collection and PropertyGrids don't seem to like those, they like to be bound to objects with properties. On the other hand my parameters have different value types and that is something the Data Grids do not favor, there the columns always have the same value editor (e.g. Check box, Date picker etc).
Does anybody know a reliable control that supports binding to a collection and individual value editors per row?
Other requirements are hierarchical data representation, validation and a search function.
DataGrid lets you use a DataGridTemplateColumn, where you can specify a template that will be applied to each cell in that column. This template could contain a UserControl that you have defined, which analyzes its DataContext and shows the appropriate control. (This will be quite a bit of work, though, so if there exist out-of-the-box solutions for this, you should use that instead.)
After a while of investigation I found out that all frameworks have the ability to apply individual cell editors in columns.
This is usually done in the column definition. A grid has a Columns collection. Each column can set a CellTemplateSelector which was the key to my initial problem.
Here is a little snippet for the Telerik grid view, but down to the CellTemplateSelector they all behave the same, as far as I can judge. All the vendor of 3rd party UI libs seems to have copied the behviour of the WPF DataGrid, of course.
<telerik:RadGridView x:Name="radGridView"
AutoGenerateColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name}" Header="Parameter" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding Value}" Header="Value">
<telerik:GridViewDataColumn.CellTemplateSelector>
<telerik:ConditionalDataTemplateSelector>
<telerik:DataTemplateRule Condition="PropertyId < 1">
<DataTemplate>
<TextBox Text="{Binding Value, StringFormat=c}"/>
</DataTemplate>
</telerik:DataTemplateRule>
<telerik:DataTemplateRule Condition="PropertyId > 0">
<DataTemplate>
<CheckBox IsChecked="{Binding Value}" />
</DataTemplate>
</telerik:DataTemplateRule>
</telerik:ConditionalDataTemplateSelector>
</telerik:GridViewDataColumn.CellTemplateSelector>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
In this example the ItmesSource of the grid is bound to my view model that contains Name, Value and PropertyId properties. Based on the PropertyId a control is selected. The thing I like about the Telerik control is that I don't need code-behind since the ConditionalDataTemplateSelector is available in that framework. Better for MVVM to keep your view clean of code behind, I guess.
UPDATE:
Just received an answer from Syncfusion, they say:
We can load different cell editors in one column. For that we have to Handle dataGrid.Model.QueryCellInfo even and we have to change the CellType based on data. We can't avoid code behind. But this can be achieved using Behaviors.

Can I implement ScrollToHorizontalOffset() functionality in XAML? (for a dynamic list)

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.

Categories