Search code examples
c#xamlwindows-phoneitemscontrol

Add a TextBox as the last element of an ItemsControl with WrapPanel


I am trying to implement the following scanarios enter image description here

APPROACH SO FAR

Tried to implement it with an ItemsControl (with WrapPanel) and a TextBox wrapped inside a WrapPanel, but it does not have a desired output as there are two WrapPanels wrapping separately

<toolkit:WrapPanel Orientation="Horizontal">
     <ItemsControl ItemsSource="{Binding someThing}">
         <ItemsControl.ItemTemplate>
              <DataTemplate>
                   <Grid>
                       <Border>
                           <TextBlock Text="somesomething" />
                       </Border>
                   </Grid>
               </DataTemplate>
         </ItemsControl.ItemTemplate>
         <ItemsControl.ItemsPanel>
             <ItemsPanelTemplate>
                <toolkit:WrapPanel Orientation="Horizontal" />
              </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
      </ItemsControl>
      <TextBox/>
 </toolkit:WrapPanel>

I am thinking if I can add the TextBox at the END of the ItemsControl, but failed to do so. Please specify if there is any other workaround/ solution to any of my approaches


Solution

  • You need to use DataTemplateSelector for the ItemsControl and specify different templates for different list items.

    public class BlockItem
    {
        // TODO
    }
    
    public class BoxItem
    {
        // TODO
    }
    
    public class MyTemplateSelector : DataTemplateSelector
    {
        public DataTemplate BlockTemplate { get; set; }
        public DataTemplate BoxTemplate { get; set; }
    
        protected override DataTemplate SelectTemplateCore(object item)
        {
            if (item is BlockItem) return BlockTemplate;
            else if (item is BoxItem) return BoxTemplate;
    
            return base.SelectTemplateCore(item);
        }
    }
    

    XAML:

    <ItemsControl ItemsSource="{Binding someObject}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <toolkit:WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplateSelector>
            <local:MyTemplateSelector>
                <local:MyTemplateSelector.BlockTemplate>
                    <DataTemplate>
                        <Grid>
                            <TextBlock Text="something"/>
                        </Grid>
                    </DataTemplate>
                </local:MyTemplateSelector.BlockTemplate>
                <local:MyTemplateSelector.BoxTemplate>
                    <DataTemplate>
                        <Grid>
                            <TextBox Text="something"/>
                        </Grid>
                    </DataTemplate>
                </local:MyTemplateSelector.BoxTemplate>
            </local:MyTemplateSelector>
        </ItemsControl.ItemTemplateSelector>
    </ItemsControl>
    

    And you then add different types of objects to your items source:

    someObject.Add(new BlockItem());
    someObject.Add(new BlockItem());
    someObject.Add(new BlockItem());
    someObject.Add(new BlockItem());
    someObject.Add(new BoxItem());
    

    If you want the TextBox to be the last element, then you need it to be the last item in your ItemsSource list.