2013-04-24 3 views
5

this question과 비슷한 문제가 발생하지만 VirtualizingStackPanel.IsVirtualizing="False"은 내 문제를 해결하지 못했습니다. 동일한 문제에 직면 해있는 사람이 있습니까? ItemContainerGenerator.ContainerFromItem()은 null을 반환합니다. VirtualizingStackPanel.IsVirtualizing = "False"

this.ItemContainerGenerator.ContainerFromItem(this.Items[0]) as ComboBoxItem; 

어떤 제안이 있습니까,

것은, 나는 정의 콤보가

<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); 
} 
+0

사용자 정의 콤보 상자의 모양은 무엇입니까? ComboBox의 전체 XAML을 게시하십시오. – Clemens

+0

VirtualizationStackPanel.IsVirtualizing = "False"를 ItemsPanelTemplate으로 설정하기 전에 제안한 내용이 약간 개선되었습니다. 그러나 그것은 여전히 ​​null이 아닌 곳을 반환합니다. –

+0

MultiSelectionComboBox가 실제로 컨테이너 유형으로 ComboBoxItem을 사용합니까? 그런데 StackPanel에서'VirtualizingStackPanel.IsVirtualizing'을 설정해도 효과가 없습니다. 가상화가 문제가되지 않는다고 생각합니다. – Clemens

답변

12

this.ItemContainerGenerator.ContainerFromItem(item)

+1

Brilliant! 나는 다른 제안을 시도하는 문제에 대해 1 시간을 잃어 버렸고이 대답이 나를 도왔다! – Daniel

+2

적어도 윈도우즈 폰 8에서는 작동하지 않습니다.) –

+0

이런 몰리는 저에게 몇 가지 문제를 해결했습니다! – Puffin

2

사용 ItemContainerGenerator.StatusChanged 이벤트 전에 UpdateLayout()을 실행하려고 :

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); 
     } 
    } 
} 
0

내 논리가 SelectionChanged 이벤트에 있었기 때문에 Listbox.SelectedItem이 null이 아니며 더 이상하지 않은 경우에도 ItemContainerGenerator.ContainerFromItem 메서드가 항상 null을 반환하는 이유가 궁금했습니다. Virtualisation wa 꺼져! ItemContainerGenerator.Status을 보면 나는 Primitives.GeneratorStatus.NotStarted이라는 것을 보았습니다. ItemContainerGenerator.Status == Primitives.GeneratorStatus.ContainersGenerated에 대한 간단한 테스트를 추가하고 마침내 그 방법으로 해결하여 Status_Changed 이벤트에 서브 스크립 션 할 필요가 없습니다.