WPF:如何重新创建ItemContainer? [英] WPF: how to recreate ItemContainer?
问题描述
在上一个问题之后如何更改ComboBox项的可见性,由于该问题已稍有更改,因此我决定打开一个新帖子来解决该问题.对于那些不想阅读上一篇文章的所有评论的人,情况就是这样.
Following my previous question How to change ComboBox item visibility, since the problem is slightly changed i decided to open a new post to solve the it. For those who don't want to read all the comments on the previous post, here is the situation.
我有一个在运行时生成的DataGrid.此数据网格的每一列在标题内都有一个组合框.所有这些组合框都具有相同的源",即可观察到的类项目集合.每个项目都显示一个我在组合框的ItemContainerStyle中使用的属性,以决定每个ComBoBoxItem是否应该可见.
I have a DataGrid that is generated at run time. Each column of this datagrid have a combobox inside the header. All those comboboxes have the same Source, that is an observable collection of a class item. Every item show a property that i use in the ItemContainerStyle of the comboboxes, to decide whether each ComBoBoxItem should be Visible or not.
现在,据我所知,WPF是这样工作的:如果视图包含诸如combobox或treeview之类的控件,则在不需要之前不会生成它们的项(即ComboBoxItem,TreeViewItem ...).打开组合框的下拉菜单时的示例).如果我应用ItemContainerStyle,这将告诉目标应如何创建其项目.问题在于,在生成此项目的那一刻,我需要对样式进行的每项更改都不会保存.
Now, as far as i know, WPF work this way : if a view contain controls like combobox or treeview, then their items (i.e. ComboBoxItem, TreeViewItem...), won't be generated until it's not necessary (for example when the dropdown of a combobox is opened). If i apply an ItemContainerStyle, this will tell to the target how its items should be created. The problem is, that at the moment that this items are generated, every change i need to apply to the style, won't be saved.
这是我的代码:
<DataGrid HeadersVisibility="Column" Name="griglia" Grid.Row="2" ItemsSource="{Binding Path=Test}" AutoGenerateColumns="True" IsReadOnly="True" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="ContentTemplate" >
<Setter.Value>
<DataTemplate DataType="DataGridColumnHeader" >
<ComboBox ItemContainerStyle="{StaticResource SingleSelectionComboBoxItem}" DisplayMemberPath="Oggetto" Width="100" Height="20" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.Selezione, UpdateSourceTrigger=LostFocus}" SelectionChanged="SingleSelectionComboBox_SelectionChanged">
</ComboBox>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
ItemContainerStyle:
ItemContainerStyle:
<Style x:Key="SingleSelectionComboBoxItem" TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}">
<Style.Triggers>
<DataTrigger Binding="{Binding Selezionato}" Value="True">
<!-- Hide it -->
<Setter Property="Visibility" Value="Collapsed" />
<!-- Also prevent user from selecting it via arrows or mousewheel -->
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
SelectionChanged:
SelectionChanged:
private void SingleSelectionComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.RemovedItems.OfType<PopolazioneCombo>())
{
item.Selezionato = false;
}
foreach (var item in e.AddedItems.OfType<PopolazioneCombo>())
{
item.Selezionato = true;
}
}
我的要求是,如果在N个组合框中的任何一个中都选择了一个项目,那么该项目将无法被任何人选择,直到他失去SelectedItem状态.例如,假设我有2个组合框和4个项目(x,y,a,b)的集合.如果在ComboBox1中选择了x,则直到ComboBox1的SelectedItem更改(例如,从x更改为y)之前,都无法在2个ComboBox中选择x.现在,我什至可以接受以下事实:如果下拉菜单中的项目使事情变得更容易,则该项目将被禁用;我只需要一个事实,即如果已经选择了该项目,则无法再次选择该项目.
My requirement is that, if in any of the N combobox an item is selected, then, that item cannot be selected by anyone, until he lose the SelectedItem status. For instance let's assume i have 2 combobox and a collection of 4 Item (x,y,a,b) . If x is selected in ComboBox1, then x can't be selected in none of the 2 ComboBox until the SelectedItem of the ComboBox1 change (from x to y for instance). Now i can even accept the fact that the item in the dropdown is just disabled if it makes the things easier, i just need the fact that it cannot be selected again if he is already selected.
问题是此解决方案适用于具有ItemContainerGenerator.Status = NotStarted的每个ComboBox(这意味着仍未创建ComboBoxItem).如果我打开组合框的下拉列表,则无论我做什么,它的ComboBox项都将保留其样式(因为ItemContainerGenerator.Status = ContainersGenerated),而我未打开的组合框会跟踪其可见性的变化.项目.
The problem is that this solution work for every ComboBox that has its ItemContainerGenerator.Status = NotStarted (this means that the ComboBoxItem are still not created). If i open the dropdown of a combobox, then its ComboBox items will retain their style no matter what i do (cause ItemContainerGenerator.Status = ContainersGenerated), while the combobox that i didn't opened keep track of the changes in the visibility of the items.
我正在寻找一种重新创建这些项目的解决方案,以使将应用具有可见性更改的新样式
I'm Looking for a solution to recreate these items do that the new style with the changes in the visibility will be applied
推荐答案
在互联网上进行了一次幸运的研究(即我找到了正确的关键字组合)之后,我发现了这种出色的方法,因此这里提供了更新的解决方案:>
after a lucky research on internet (i.e. i've found the correct combination of keyword), i found this wonderful method, so here the updated solution:
private void ComboBox_DropDownOpened(object sender, EventArgs e)
{
ComboBox c = sender as ComboBox;
c.Items.Refresh();
}
将此事件添加到xaml中,使其变为:
add this event in the xaml so that it became:
<ComboBox DropDownOpened="ComboBox_DropDownOpened" ItemContainerStyle="{StaticResource SingleSelectionComboBoxItem}" DisplayMemberPath="Oggetto" Width="100" Height="20" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGrid}},Path=DataContext.Selezione, UpdateSourceTrigger=LostFocus}" SelectionChanged="SingleSelectionComboBox_SelectionChanged"/>
神奇的是,组合框显示了正确的更改.现在我不再是背后的代码狂热者,因此,如果有办法做到这一点,可以向我的收藏夹中添加一个属性,或者通过xaml这样做会更好
and magically the combobox show the correct changes. Now i'm not a big fan of code behind, so if there is a way to do this adding a property to my Collection, or via xaml it would be better
这篇关于WPF:如何重新创建ItemContainer?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!