WPF Hiding the First Item of an ItemsControl (Combobox,textbox,etc) - wpf

Is there a way to hide the first item's (combobox)control in an itemscontrol in xaml in pure view only ?
<ItemsControl ItemsSource="{Binding QueueConditionCollection.Collection,
NotifyOnSourceUpdated=True}"
AlternationCount="2">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ComboBox Name="cmbLogicalOperator"
ItemsSource="{BindingLogicalOperatorCollection.Collection}"
SelectedItem="{Binding LogicalOperatorCollection.Selected,UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
Actual Scenario:
Hide the the control if the collection has only 1 item:
See this picture.

You can declare a boolean property which will return false if Collection.Count() == 1 and use a boolean to visibility converter for your combo box

Related

Recycling of Combobox within a ListView causes null values in SelectedValue

I reproduced the issue by creating a simple UWP application with a ListView and a DataTemplateSelector.
<DataTemplate x:Key="DetailCombo" x:DataType="classes:Question">
<ItemsControl x:Name="questionItemsControl">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding QuestionText}"/>
<ComboBox x:Name="AnswerComboBox" ItemsSource="{Binding AnswerOptions, Mode=OneWay}" SelectedIndex="{Binding AnswerIndex, Mode=TwoWay}"/>
</StackPanel>
</ItemsControl>
</DataTemplate>
For a simple Listview:
<ListView x:Name="dataTemplateSelectorList"
SelectionMode="None"
ItemsSource="{Binding Questions}"
ItemTemplateSelector="{StaticResource QuestionDataTemplateSelector}">
</ListView>
When I put a breakpoint on the setter of "AnswerIndex" I see that the value of -1 is set when I start scrolling through the list. This happens when the list is recycling the listviewitem. When I bind "SelectedValue" the value of null is set while scrolling.
Has anyone experienced this before and has a good solution for it? Now I just check if the value is null or -1 in the setter of binding-property in the viewmodel. But it feels strange that the framework updates the values upon recycling the listviewitem.
I did see the same behavior in the Microsoft.UI.Xaml.Controls.RadioButtons component.

WPF DataGrid ItemsSource - Change from ComboBox

Here is a snippet of XAML:
<ComboBox ItemsSource="{Binding UnileverDataSet.Tables, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Margin="5" x:Name="TableNameComboBox">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding TableName}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<DataGrid Margin="5" AutoGenerateColumns="True" ItemsSource="{Binding UnileverDataSet.Tables[TableNameComboBox.SelectedIndex]}"
UnileverDataSet is a DataSet made up of about 12 DataTables
The idea here is that when the ComboBox value changes, the DataGrid should update based on the index value from the ComboBox.
Is this possible or should I look at another way of doing this?
If I do: UnileverDataSet.Tables[0], then all works and data displays correctly.
You can do element binding with combobox..
Your combox will display list of items in the "UnileverDataSet.Tables" collection. When ever your select a item in Combo box the selected item will bounded to the Datagrid Items source (since we are using element binding)
Here is the sample code
<DataGrid Margin="5" AutoGenerateColumns="True" ItemsSource="{Binding SelectedItem,ElementName=TableNameComboBox}">

Trouble binding selected item in nested Listview

I currently use a listview nested inside a listview as a way to show a Knockout style tournament graphically, backed up in ViewModel by SectionTreeOne, which contains a List of Lists of objects "TournamentNode". I cannot however get my selected "Tournament Node" to bind when I click on it.
<Grid Grid.Row="2">
<ListView ItemsSource="{Binding SectionTreeOne}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate >
<DataTemplate>
<ListView ItemsSource="{Binding}" SelectionMode="Single"
SelectedItem="{Binding SelectedTournamentNode}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
C# binding:
Collection
public List<List<TournamentNodeModel>> SectionTreeOne
{
get { return _sectionTreeOne; }
set
{
_sectionTreeOne = value;
base.OnPropertyChanged("SectionTreeOne");
}
}
Selected Item:
public TournamentNodeModel SelectedTournamentNode
{
get { return _selectedTournamentNode; }
set
{
if (value == _selectedTournamentNode)
return;
_selectedTournamentNode = value;
base.OnPropertyChanged("SelectedTournamentNode");
}
}
Try with the folowing binding:
SelectedItem="{Binding SelectedTournamentNode, Mode=TwoWay}"
Keep in mind that WinRT always use the OneWay binding mode as default unlike in WPF where it automatically selects a binding mode depending on the property nature or accessibility.
A good principle I used with WinRT to avoid this kind of mistake is to always explicitely specify the binding mode.
So I finally figured out what were the mistakes in your binding. Firstly, the SelectedItem binding mode has to be set to TwoWay explicitely as I stated above.
Secondly, the nested list was binding to an inner list in the SectionTreeOne list, therefore if you want to bind SelectedItem to a property on your view model, you have to rebind this property to the DataContext of the parent list using named elements. You were actually trying to bind to a non-existant property on the inner list instead of binding to the view model where the property is located.
<ListView x:Name="listView" ItemsSource="{Binding SectionTreeOne}">
...
<ListView.ItemTemplate >
<DataTemplate>
<ListView ItemsSource="{Binding}" SelectionMode="Single"
SelectedItem="{Binding Path=DataContext.SelectedTournamentNode, ElementName=listView, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Do read the Visual Studio debugger output, it has really useful information about binding errors that could occur in the binding chain, especially if you bind a list nested in another list, it will save you lot of headaches!

Relative Binding in Silverlight

I have an ItemsControl in my application. The page associated with the ItemsControl is bound to a view-model. The view-model includes two properties: People and Options. For each person, I want to display a list of options in a ComboBox. The options are defined in my view-model. My code looks like the following:
<ItemsControl ItemsSource="{Binding Path=People}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox ItemsSource="Options" DisplayMemberPath="FullName" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
However, because each Item represents a Person, the ComboBox is looking at the Person object for a property called "Options". How do I reference the view model for the from the ComboBox instead of the Person?
Thanks!
You can use the following technique
<ComboBox ItemsSource="{Binding ElementName=LayoutRoot, Path=DataContext.Options}" DisplayMemberPath="FullName" />
Assuming that your LayoutRoot's DataContext is the View Model. If not you can give your ItemsControl a name and use that for the ElementName.

Binding a WPF ComboBox to a different ItemsSource within a ListBox DataTemplate

I have a ListBox that contains a textbox and a combobox in its datatemplate:
<ListBox Height="147" Margin="158,29,170,0" Name="PitcherListBox" VerticalAlignment="Top" ItemsSource="{Binding SomeCollectionOfObjects}" Background="Black">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=Name}" />
<ComboBox ItemsSource="{Binding LocalArrayOfIntsProperty}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I want to bind the listbox to a collection of objects (which I've done successfully), but I want the combobox in the above datatemplate to have its itemssource set to a local property on the window (array of ints). I still want the combobox to have a two-way bind between its selected item and a property on the collection of objects...
I have the following in code:
PitcherListBox.DataContext = this;
Basically in the end, I want the combobox within the listbox to have a different itemssource than the listbox itself. I can't seem to figure out how to change the ComboBox's ItemsSource in XAML. Can someone provide me some feedback? Thanks!
Try this:
<ComboBox ItemsSource="{Binding LocalArrayOfIntsProperty, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourWindowTypeHere}}}" />
Note that you need to replace YourWindowTypeHere with the type of the Window containing the LocalArrayOfIntsProperty! Also remember that you will need to define an xml namespace for that type!

Resources