WPF: set GridView ColumnHeaderContainerStyle code behind - wpf

So i have my ListView and GridView inside ListView.View:
<GridView ColumnHeaderContainerStyle="{StaticResource ListViewHeaderDefaultStyle}" >
And i Added several Styles that i am want to change via code behind.
but all found is how to change ItemContainerStyle

Just give your GridView an x:Name in your XAML:
<ListView>
<ListView.View>
<GridView x:Name="gv">
...
</GridView>
</ListView.View>
</ListView>
...and you will be able to access it in the code-behind as usual:
gv.ColumnHeaderContainerStyle = this.FindResource("ListViewHeaderDefaultStyle") as Style;

Related

Attach behavior to Items in GridView

I've got a ListView with a GridView used to present Items. ListView is defined like
<ListView ItemsSource={Binding ...}>
<ListView.View>
<GridView>
<GridViewColumn>...</GridViewColumn>
<GridViewColumn>...</GridViewColumn>
<GridViewColumn>...</GridViewColumn>
...
</GridView>
</ListView.View>
</ListView>
How can I attach custom behavior to each Item in the List (one behavior for all items)?
Thanks in advance!

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>

Get GridViewColumn from control inside DataTemplate

Example:
<ListView Name="lvAnyList" ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="xx" DisplayMemberBinding="{Binding XX}" CellTemplate="{DynamicResource MyDataTemplate}"/>
<GridViewColumn Header="yy">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding YY}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
If I access the TextBlock inside DataTemplate I will have access to information about the bound path.
But I don't know how to find (starting from the TextBlock) its containing GridViewColumn (which is in the GridViewRowPresenter columns list) and compare it to the grid's GridViewColumn (from GridViewHeaderRowPresenter column list) to get the header's name.
At the end I should have the pairs: xx->XX, yy->YY
I can find a list of all TextBlocks inside ListView by using this:
GridViewRowPresenter gvrp = ControlAux.GetVisualDescendants<GridViewRowPresenter>(element).FirstOrDefault();
IEnumerable<TextBlock> entb = GetVisualDescendants<TextBlock>(gvrp);
I can find a list of all GridViewColumnHeaders:
GridViewHeaderRowPresenter gvhrp = ControlAux.GetVisualDescendants<GridViewHeaderRowPresenter>(element).FirstOrDefault();
And I cannot find the connection between the TextBlocks and the GridViewColumns...
I hope this is understandable.
GridViewColumns are abstract objects they never appear anywhere in the UI, you can try to name the column and bind it to the Tag of a control where you need it using ElementName or if that fails a Source with x:Reference on the name.

How to get selected item of a nested listview?

i have a nested listview, i can bind the selected item of the basic listview to my viewmodel but not my selected item of the nested listview ( in the basic listview ) I just do:
this is my listview:
<ListView Height="155" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="False" Margin="24,506,280,169" Background="#CDC5CBC5"
dd:DragDrop.DropHandler="{Binding}" SelectedItem ="{Binding Path=SelectedCluster,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" ItemsSource="{Binding Path=Clusters,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Titel" DisplayMemberBinding="{Binding Title}"/>
<GridViewColumn Header="Questions">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ListView DataContext="{Binding}" ItemsSource="{Binding ExaminationQuestions}" SelectedItem="{Binding Path=SelectedExaminationQuestionInCluster,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}">
<ListView.View>
<GridView>
<GridViewColumn Header="Description" DisplayMemberBinding="{Binding Question.Description}"/>
</GridView>
</ListView.View>
</ListView>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Viewmodel:
public ExaminationQuestion SelectedExaminationQuestionInCluster
{
get { return selectedExaminationQuestionInCluster; }
set { selectedExaminationQuestionInCluster = value;
OnPropertyChanged("SelectedExaminationQuestionInCluster");
}
}
Someone who knows what i am doing wrong? If i set a breakpoint of the setter of selecteditem of the second listview. He just ignores that..
Thanks
My guess is the binding is probably incorrect. In your outer ListView, you bind to "Clusters". Your inner ListView is probably trying to bind to "SelectedExaminationQuestionInCluster" on the current Cluster. You can see if this is the case by using snoop. It's a valuable tool when debugging WPF apps. It will highlight broken bindings in red and tell you what's wrong with them.
If you want to bind to "SelectedExaminationQuestionInCluster" on the parent DataContext, you could use this syntax:
SelectedItem="{Binding Path=DataContext.SelectedExaminationQuestionInCluster,
ElementName=OuterListView}"
You'll have to give the outer ListView a name of course.
EDIT: I just realized this might not make sense. If each Cluster has its own collection of ExaminationQuestions, then each Cluster should also have a SelectedExaminationQuestion. The parent DataContext should not have any concept of a SelectedQuestion unless it is shared amongst all Clusters.

How to bind to ColumnCollection for a GridView using XAML

I have a collection of objects which I would like to represent columns in a GridView.
Currently I am binding individual columns in my GridView to items in the collection like this:
<ListView>
<ListView.View>
<GridView>
<GridViewColumn Header="{Binding Path=MyColumns[0].Title}"></GridViewColumn>
<GridViewColumn Header="{Binding Path=MyColumns[1].Title}"></GridViewColumn>
<GridViewColumn Header="{Binding Path=MyColumns[2].Title}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
This works well, but what I really want to do is to bind to the collection itself (since the number of items in the collection might change at run-time). I would like to accomplish this in XAML. What I have in mind is something like this (note this does not work - the ColumnsSource attribute is make-believe):
<ListView>
<ListView.View>
<GridView ColumnsSource="{Binding Path=MyColumns}">
</GridView>
</ListView.View>
</ListView>
Can this be done? If so, how?
You can use an attached property to create a ColumnsSource property, see this question for an example.

Resources