WPF: Deselect all my Checkbox when one is selected - wpf

This is my first ListView row column that contain CheckBox:
<GridViewColumn Width="40" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Name="cbSelectInterface" IsThreeState="False" ></CheckBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
How can i add the option to check only one CheckBox in specific Row and what i choose another CheckBox and check this control all other CheckBox become non selected ?

What about binding the CheckBox's IsChecked property to the ListViewItem's IsSelected property? If SelectionMode is set to Single, then you'll only be able to select one row and one checkbox.
<ListView ItemsSource="{Binding Source={StaticResource TestDataSource}}"
SelectionMode="Single">
<ListView.View>
<GridView>
<GridViewColumn Width="30">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected,
RelativeSource={RelativeSource
AncestorType={x:Type ListViewItem}}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding}" />
</GridView>
</ListView.View>
</ListView>
You can then use the ListView's SelectedItem to know which row is the one with the checked CheckBox.

In WPF, there is no control that automatically does what you want. However, implementing your requirement is simple, or at least, would be simple if you were using data binding as is customary in WPF applications. In that case, your view model or code behind would have an object (that would be data bound to the ListView.ItemsSource property) that contains all of the data items.
All you need to do when one of the Checkboxes is checked is to iterate through each item in the data bound collection and set their properties that are data bound to the Checkbox to false:
foreach (var item in YourDataBoundCollection)
{
item.PropertyDataBoundToCheckBox = false;
}
If you have implemented the INotifyPropertyChanged interface on your data class as you should have, then the UI will be automatically updated.
The only remaining question is how do you know when a CheckBox has been checked? The simplest 'non MVVM' way would be to add a handler for the CheckBox.Checked Event.

Related

How to bind to template-generated elements in a ListView

I have a ListView where for each item I'd like to add a TextBox for user input, and then be able bind to its content per selected item (or using an indexer) from outside of the ListView.
To illustrate:
<ListView Name="lv" ItemsSource="{Binding Source={StaticResource lvSrc1}}">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Loc">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Name="tbGv" Text="User input" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
<TextBlock Text="{Binding ElementName=lv, Path=SelectedItem[tbGv]}" />
Of course the above binding won't work, as SelectedItem returns an object from the underlying collection, which has nothing to do with the added TextBox.
How can I access the generated TextBoxes using pure XAML?
Edit:
I've now found a couple of posts with somewhat similar problems, where solutions presented are trickier than I expected and not based on XAML.
So rather, would it be possible to access ListViewItem (not the data its bound to) and its properties? This way I think I could pass text from my TextBox through the Tag property of ListViewItem.
I'm quite new to WPF so I assume that my problem and its phrasing is ridiculous, but please be gentle ;)

WPF - Retrieve the object binded instead of a single property of the object

I have a checkbox and a textblock inside a stackpanel. When the textblock is clicked, the checkbox should be checked. Actually, it is a set of checkboxes and set of text blocks. Need to retrieve the value ID ( this is a property of the class "SomeClass" of the checkbox. But what has been binded to the Textblock is the name. My question is how do I retrieve the the whole object ?
<ListView>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<ItemsControl ItemSource="{Binding SomeClass} ">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<CheckBox...../>
<TextBlock ...Text={Binding Name}/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView>
I am making use of the MouseLeftButton event of TextBlock. I can retrieve the Name, but what I need is the whole obect itself so that I can retrieve the ID property . Any solution to this ?
Use {Binding} without a property path or {Binding Path=.}

Data binding to a ViewModel property from a collections Binding?

I will try to keep this as succinct as possible.
I have a ViewModel with a collection of Models (i.e. Airplanes).
I have a Xaml page that is binded to the ViewModel.
The Xaml page has a DataGrid that is binded to the Airplanes collections.
For one of the DataGrid column templates, I want it to show a list of "EngineComponents", where EngineComponents is a collection of items defined in the ViewModel.
The catch is this:
The EngineComponents is a collection of parts that is essentially static. All Airplance rows in the DataGrid should show the same list of EngineComponents.
Airplanes
How to solve this EngineComponents binding question without writing extra code (event handlers, etc)?
You need to use a RelativeSource. I'll use a ListView in my example, but the ideas the same.
<UserControl ... DataContext="{Binding ...}">
<ListView ItemsSource="{Binding Airplanes}">
<ListView.View>
<GridView>
<GridViewColumn Header="Drawing No." Width="80">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding DataContext.AvailableAirplanes,RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedItem="{Binding Airplane}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</UserControl>

WPF binding to CurrentItem

I have a WPF model which contains a viewsource, a listview, and a button, which is meant to execute an ICommand in the viewmodel for the item selected in the listview.
<Window.Resources>
<CollectionViewSource x:Key="teachingSessionsViewSource" d:DesignSource="{d:DesignInstance {x:Type local:TeachingSessionListItem}, CreateList=True}"/>
</Window.Resources>
...
<GroupBox Header="All Sessions"
DataContext="{Binding Source={StaticResource teachingSessionsViewSource}}">
<StackPanel>
<ListView x:Name="TeachingSessionList"
ItemsSource="{Binding}"
SelectedItem="{Binding Path=/}">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource noHeaderStyle}">
<GridViewColumn DisplayMemberBinding="{Binding SessionDate}"/>
<GridViewColumn DisplayMemberBinding="{Binding PresenterInitials}" Width="30" />
</GridView>
</ListView.View>
</ListView>
<Button Content="Un-Assign" Margin="5,5" Command="{Binding Path=/UnAssignPresentation}"
</StackPanel>
</GroupBox>
The problem is that the ICommand UnAssignPresentation is always executed on the first item in the list, regardless of which item is selected in the listview. That is to say, the currentItem property of the CollectionViewSource does not seem to be bound to the ListView.
What am I doing wrong? Thank you very much.
Try adding IsSynchronizedWithCurrentItem="True" to your ListView.
Also, prefer binding listview to a collection in your view model and not to a resource.
You can then add a property to the view model for the selected item
and bind the listview's selected item to that property in the view model
and either bind the button's command to a command in the view model that acts on the current item,or pass the item you want to act on via the command parameter binded to the selected item.

Access control binding information from GridViewColumn

I have code like this
<GridViewColumn Header="Status" Width="75" DisplayMemberBinding="{Binding Path=TimesheetStatus}"/>
<GridViewColumn Header="Reviewed?" Width="70">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="1,2,1,0" IsEnabled="{Binding Path=EnableReview}" IsChecked="{Binding Path=IsReviewed}" Checked="reviewedCheckBox_Checked"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
I am able to access the displaymemberbinding property (TimeSheetStatus) for Gridviewcolumn Status.
But I want to know how can I access the IsChecked Binding property (IsReviewed) from the "Reviewed?" Gridviewcolumn.
Any help?
because you are using a data template, there is no nice way to get there, but if you only wants to get to this specific column binding you can try debug the application and look at the column in debug view till you get the to checkbox, write this path in your code and use the BindingOperations helper class to get the binding of the relevant property in your check box

Resources