WPF ComboBox in grid - how to specify search path in viewmodel - c#

We have a DataGridTemplateColumn that uses a ComboBox in the DataTemplate:
<DataGridTemplateColumn Header="Things">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox
IsTextSearchEnabled="True"
TextSearch.TextPath="Name"
ItemsSource="{Binding Things}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Index}" Margin="0,0,12,0" />
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
We need to let the user specify the search path for the ComboBox.
TextSearch.TextPath="{Binding SearchPath}"
How do I specify that this binding refers to the top-level viewmodel, not the current item from the Things collection (which Name and Index refer to)?
Thanks for any insights --

Related

WPF use static resource in DataTemplate

I have a user control defines in my Application.Resources and want to use it as a DataTemplate for a ComboBox.
The user control:
<TextBlock
x:Key="ListItemView"
Text="{Binding Name}"
ToolTip="{Binding ToolTip}"/>
The Combox Box in my Window:
<ComboBox
ItemsSource="{Binding ComboBoxItems}"
SelectedItem="{Binding SelectedComboBoxItem}">
<ComboBox.ItemTemplate>
<DataTemplate>
<!-- TODO how to use StaticResource ListItemView in here? -->
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
You must put your user control into DataTemplate
<DataTemplate x:Key="ListItemView">
<TextBlock Text="{Binding Name}"
ToolTip="{Binding ToolTip}"/>
</DataTemplate>
Use your data template
<ComboBox ItemsSource="{Binding ComboBoxItems}"
SelectedItem="{Binding SelectedComboBoxItem}"
ItemTemplate="{StaticResource ListItemView}">
</ComboBox>

How to fix an endless rendering / measure loop with WPF?

I have the following XAML code implementing a data grid with DirectionalNavigation = Cycle.
<DataGrid
KeyboardNavigation.DirectionalNavigation="Cycle"
x:Name="ToolPathGridView"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True"
CanUserAddRows="False"
SelectionUnit="FullRow"
CanUserDeleteRows="False"
SelectionMode="Single"
ItemsSource="{Binding
ToolPath.ToolPath,
Mode=OneWay,
Converter={StaticResource IndexedConverter}}"
AutoGenerateColumns="False"
SelectedIndex="{Binding SelectedIndex, Mode=TwoWay}">
<DataGrid.Resources>
<SolidColorBrush
x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
Color="DarkGray"/>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
Id
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Index}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=SwivelAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Swivel}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=ChuckAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Chuck}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock
Text="{Binding Source={StaticResource T9N},
Path=VerticalAxis}" />
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Label Content="{Binding Value.ToolAxes.Vertical}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Using the arrow keys I can move up and down the rows.
If the last row in the data-grid is selected, as above, and the down arrow is pressed then the first row in the list should become selected. However WPF goes into an endless measure / arrange loop.
I previously had custom user controls in each of the cell templates but have removed them and replaced them with plain labels just in case my controls were behaving badly.
Does anybody have an idea if this is a bug in WPF or a problem with my usage of the data grid?

Can i make UpDown Column at DataGrid?

Can i make UpDown Column at DataGrid?
I have simple DataGrid:
<DataGrid Grid.Row="0" Grid.Column="0">
<DataGrid.Columns>
<DataGridTextColumn Header="Name"> </DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
And i want to make UpDown column. Can i do that?
Thank you!
P.S. i mean something like numericUpDown counter. :up: [1], down: [0].
I think you can do something like
<DataGrid>
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=AttrName}" Height="25" Width="150" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBlock Text="{Binding Path=AttrDisplayLabel}" Height="25" Width="Auto" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="10,0,0,0" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Height="25"
ItemsSource="{Binding Source={StaticResource cvsAttributes}}"
SelectedValuePath="AttributeID"
IsSynchronizedWithCurrentItem="False"
SelectionChanged="Selector_OnSelectionChanged"
SelectedValue="{Binding Path=AttributeId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
....
Just replace combo with your updown/spinner control. The celltemplate is your display... the celledittemplate is your edit control...(updown...etc...)
If you mean NumericUpDown column
you can have a template column and add NumericUpDown Control to the template
Look Here for creating custom numeric updown control or simply use one provided with WPFToolkit !!
Find Codeples for Toolkit Here

How todo nested Databinding with Windows Phone (Pivot and ListBox)

I am pretty new in the usage of the DataBinding concept in Windows Phone. I am trying to bind a Pivot page with a list of items, as well as a ListBox in each PivotItem with another list (of criterias). I have a Page with the following XAML:
<phone:Pivot Name="ItemsPivot" Title="MY APPLICATION">
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel Margin="12,17,0,28">
<ListBox Name="CriteriasListBox" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<TextBlock Text="{Binding Name}"/>
<tk:Rating />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
I then try to specify the ItemSource of each binded control in the C# code like this:
...
ItemsPivot.ItemsSource = ItemList;
CriteriasListBox.ItemsSource = CriteriaList; // <-- CriteriasListBox not accessible !!
...
But there is an error stating that "the name 'CriteriasListBox' does not exist in the current context"... As I mention, I am pretty new with this technology.
Can I have some advice, solution or resources on how do make this nested binding work?
Thank you !
Do like this,
<UserControl.Resources>
<DataTemplate x:Key="MyPivotItemTemplate">
<controls:PivotItem Header="first" >
<ListBox x:Name="CriteriasListBox" Margin="0,0,12,0" ItemsSource="{Binding CriteriaList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="132">
<TextBlock Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</controls:PivotItem>
</DataTemplate>
</UserControl.Resources>
Then in your pivot
<Pivot ItemsTemplate="{StaticResource MyPivotItemTemplate}" Items="{Binding ItemList}"
One of the ways if you have different criteria list for different items is to add criteria list property to your PivotItemViewModel. Your c# code will look like this
ItemsPivot.ItemsSource = ItemList;
where every item in ItemList contains CriteriaList. Your xaml code will look like
<phone:Pivot Name="ItemsPivot" Title="MY APPLICATION">
<phone:Pivot.ItemTemplate>
<DataTemplate>
<StackPanel Margin="12,17,0,28">
<TextBlock Name="PivotTextBlock" Text="{Binding Name}"/>
<ListBox ItemsSource="{Binding Criterions}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" >
<TextBlock Name="ListTextBlock" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</phone:Pivot.ItemTemplate>
</phone:Pivot>
Binding for PivotTextBlock retrieves Name property from the PivotItemViewModel. Binding for ListTextBlock retrieves Name property from Criteria.
If criteria list the only in your application here is a good start
Here is another good way I found...
http://www.codeproject.com/Articles/47229/A-LINQ-Tutorial-WPF-Data-Binding-with-LINQ-to-SQL
Here is a code snippet:
<DataTemplate DataType="{x:Type LINQDemo:Category}">
<Border Name="border" BorderBrush="ForestGreen"
BorderThickness="1" Padding="5" Margin="5">
<StackPanel>
<TextBlock Text="{Binding Path=Name}"
FontWeight="Bold" FontSize="14"/>
<ListView ItemsSource="{Binding Path=Books}"
HorizontalContentAlignment="Stretch" BorderThickness="0" >
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Click="LoadIndividualBook"
CommandParameter="{Binding}"
ToolTip="Display book details">
<TextBlock Text="{Binding Path=Title}"/></Hyperlink>
...

Binding is not working with data template in data template

I have a ListView with an nested ItemTemplate for presenting orders.
Each order is presented within a Expander. These Expanders have a ContentTemplate for presenting all positions within each order. And these order positions are also in a Expander.
The ListView gets its data from an ObservableCollection (AvailableOrders) which contains all orders. These order object have a ObservableCollection "Items" holding all positions for this order.
But I'm not able to get the bindings work properly. How should I properly set the binding for the "inner expander" to show information about the items?
All ideas are appreciated!
<ListView ItemsSource="{Binding VMOrder.AvailableOrders}">
<ListView.ItemTemplate>
<DataTemplate>
<Expander Content="{Binding}">
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Order " />
<TextBlock Text="{Binding Id}" />
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.ContentTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.Template>
<ControlTemplate>
<Expander>
<Expander.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Material.Name}" />
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.ContentTemplate>
<DataTemplate>
<TextBlock Text="TEST" />
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I've figured it out now.
I need to use a relative source in the data templates and set the content property of each expander.
<ListView ItemsSource="{Binding VMOrder.AvailableOrders}">
<ListView.ItemTemplate>
<DataTemplate>
<Expander Content="{Binding}">
<Expander.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Order " />
<TextBlock Text="{Binding DataContext.Id, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" />
</StackPanel>
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.ContentTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Content="{Binding}">
<Expander.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.Material.Name, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" />
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.ContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.Material.Description, RelativeSource={RelativeSource FindAncestor, AncestorType=Expander}}" />
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
For the inner ItemsControl, you have defined the control template for the whole control. You have to define the ItemTemplate instead
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander>
<Expander.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding Material.Name}" />
</DataTemplate>
</Expander.HeaderTemplate>
<Expander.ContentTemplate>
<DataTemplate>
<TextBlock Text="TEST" />
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Categories

Resources