WPF:如何重新创建ItemContainer? [英] WPF: how to recreate ItemContainer?

查看:133
本文介绍了WPF:如何重新创建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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆