C# ItemContainerGenerator.ContainerFromItem()在VirtualzingStackPanel.IsVirtualization=”时返回null;假;
然而,C# ItemContainerGenerator.ContainerFromItem()在VirtualzingStackPanel.IsVirtualization=”时返回null;假;,c#,wpf,combobox,null,itemcontainergenerator,C#,Wpf,Combobox,Null,Itemcontainergenerator,然而,virtualizengstackpanel.isvirtualization=“False”并没有解决我的问题。有没有人面临同样的问题 问题是我有一个自定义组合框 <Style TargetType="{x:Type MultiSelectionComboBox}" > <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="ItemsPa
virtualizengstackpanel.isvirtualization=“False”
并没有解决我的问题。有没有人面临同样的问题
问题是我有一个自定义组合框
<Style TargetType="{x:Type MultiSelectionComboBox}" >
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"
VerticalAlignment="Center"
HorizontalAlignment="Center"
VirtualizingStackPanel.IsVirtualizing="False"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Orientation="Horizontal" x:Name="ItemStack" VirtualizingStackPanel.IsVirtualizing="False">
<CheckBox x:Name="CheckBoxItem"
Command="{Binding SelectItem, RelativeSource={RelativeSource AncestorType={x:Type MultiSelectionComboBox}}}"
CommandParameter="{Binding Key}"
>
</CheckBox>
<TextBlock Text="{Binding DisplayText}"></TextBlock>
</StackPanel>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid x:Name="Placement" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Border BorderThickness="1" BorderBrush="Black">
<TextBox IsReadOnly="True" Grid.Column="0"
Text="{Binding Text, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type MultiSelectionComboBox}}}">
</TextBox>
</Border>
<Popup x:Name="PART_Popup"
Grid.Column="0"
Focusable="False"
Grid.ColumnSpan="2"
IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
Placement="Bottom"
VerticalOffset="-1"
PlacementTarget="{Binding ElementName=LayoutRoot}">
<Popup.Resources>
<Style TargetType="{x:Type ScrollBar}" BasedOn="{StaticResource {x:Type ScrollBar}}">
<Style.Triggers>
<Trigger Property="Orientation" Value="Vertical">
<Setter Property="BorderThickness" Value="0"/>
</Trigger>
</Style.Triggers>
</Style>
</Popup.Resources>
<ScrollViewer x:Name="DropDownScrollViewer"
Background="{StaticResource Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
MinWidth="{Binding ActualWidth, ElementName=LayoutRoot}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained"/>
</ScrollViewer>
</Popup>
<ToggleButton IsEnabled="{Binding IsEnabled, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType={x:Type MultiSelectionComboBox}}}" Grid.Column="1" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
有什么建议吗
我真正想要的是
我想更改复选框ischecked属性,它取决于运行时可以更改的其他对象。由于整个项目的当前状态,我无法使用绑定来实现这一点,此时我无法更改该状态。基本上,一旦创建了新的MultiSelectionComboBox,我想做一些类似的事情
foreach (object item in this.Items)
{
ComboBoxItem comboBoxItem = this.ItemContainerGenerator.ContainerFromItem(item) as ComboBoxItem;
if (comboBoxItem == null)
continue;
FrameworkElement element = comboBoxItem.ContentTemplate.LoadContent() as FrameworkElement;
CheckBox checkBox = element.FindName("CheckBoxItem") as CheckBox;
checkBox.IsChecked = this.SelectedItem.Contains(item);
}
请尝试在
此.ItemContainerGenerator.ContainerFromItem(item)
之前执行UpdateLayout()
,使用组合框中的ItemContainerGenerator.StatusChanged事件,如下所示:
myComboBox.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
void ItemContainerGenerator_StatusChanged(object sender, System.EventArgs e)
{
if (myComboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
foreach (var item in myComboBox.Items)
{
var container = (ComboBoxItem)LanguageComboBox.ItemContainerGenerator.ContainerFromItem(item);
}
}
}
由于我的逻辑在SelectionChanged事件中,我想知道为什么
ItemContainerGenerator.ContainerFromItem
方法总是返回null,即使Listbox.SelectedItem
不是null,更奇怪的是,虚拟化被关闭了!查看ItemContainerGenerator.Status
我看到它是Primitives.GeneratorStatus.NotStarted
,然后我在ItemContainerGenerator.Status==Primitives.GeneratorStatus.ContainersGenerated
上添加了一个简单的测试,并最终以这种方式解决了它,不需要订阅Status\u Changed事件。这是什么您的自定义组合框看起来像什么?请发布组合框的完整XAML。您在将VirtualizingStackPanel.IsVirtualization=“False”设置为ItemsPanelTemplate之前给出的建议带来了一些改进。但是,在我不需要它的地方,它仍然返回null。您确定MultiSelectionComboBox实际使用ComboBoxItem作为容器类型吗?顺便说一下,在StackPanel上设置virtualizengstackPanel.isvirtualization
也没有效果。我想虚拟化不是这里的问题。如果我是正确的,它似乎是这样的。ItemContainerGenerator.ContainerFromItem(item)在下拉列表未打开时返回null,因此不会呈现。将IsVirtualization false设置为ItemsPanelTamplete后。在呈现下拉列表之前,是否有方法获取项目当您的ItemContainerGenerator.ContainerFromItem
运行时?您可能需要确保容器已首先生成。此外,如果不将其强制转换为ComboBoxItem
,它是否返回值ContainerFromItem
可能只是在ContentPresenter
中返回您的模板,该模板稍后会被包装在ComboBoxItem
中,因此可能强制转换无效,这就是您获得null
的原因!我在这个问题上花了整整一个小时尝试不同的建议,这个答案帮助了我!
myComboBox.ItemContainerGenerator.StatusChanged += ItemContainerGenerator_StatusChanged;
void ItemContainerGenerator_StatusChanged(object sender, System.EventArgs e)
{
if (myComboBox.ItemContainerGenerator.Status == GeneratorStatus.ContainersGenerated)
{
foreach (var item in myComboBox.Items)
{
var container = (ComboBoxItem)LanguageComboBox.ItemContainerGenerator.ContainerFromItem(item);
}
}
}