1

Edit - I revised the original text in an effort to better convey my actual question.


I'm interested in implementing a control like this in a WPF application. Basically it's a collection of strings - you can click in the blank area, and type a new string, and enter will commit a new item to the list. You can click the 'x' button to remove an item.

The screenshot below is from a website, but I have to imagine I could accomplish the same in WPF. It seems like it might be accomplished with a styled listbox, mabye?

The biggest problem I've had is that when I try to look this up, I don't even know what a control like this would be named, so researching has been a non-starter. I'm frustrated by my inability to begin researching this due to a lack of ideas as to what to search for.

screenshot

fussmonkey
  • 606
  • 5
  • 19
  • Looks like a card view to me. Many grids can switch to a view like that. (I use the exceed grid and it can do a card view like that. (Out of curiosity, what site did you see that on?). http://stackoverflow.com/a/554972/16241 – Vaccano Jun 03 '16 at 14:23
  • 1
    I don't know if there's an existing control for it, but I'm sure you could do something simiar with an `ItemsControl` templated to use a `WrapPanel` for items and with a custom `ItemsPanelTemplate`. And perhaps customized to add a `TextBox` with no borders at the very end for text input. – Rachel Jun 03 '16 at 14:24
  • 2
    It's a ListBox or ItemsControl with WrapPanel for the ItemsPanel. ItemsSource would be bound to an ObservableCollection of `Color`, `String`, Int32 (ARGB quad is 32 bits), or whatever floats your boat. Then you give ItemTemplate a DataTemplate that displays the things as colors, and some minor fiddling for the delete buttons (which are a Button with a ControlTemplate that displays a very simple Path). No custom control needed. Write it as a Style for reuse. – 15ee8f99-57ff-4f92-890c-b56153 Jun 03 '16 at 14:27
  • Oh I was thinking for the final TextBox item, you don't even need anything custom. Just have the bound item contain something like `IsNewItem=True`, and use a DataTrigger to draw the template for that item using a borderless TextBox. Then OnChange of the text, can change it to a proper item and add another new one at the end :) – Rachel Jun 03 '16 at 14:34
  • @Vaccano - Wow, I never would have guessed "card view", thanks!That screenshot is from the settings page on a [Discourse forum](http://www.discourse.org/) I run at work. – fussmonkey Jun 03 '16 at 14:54
  • I think is is pretty close to this but just use a WrapPanel https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.itemspanel(v=vs.110).aspx – paparazzo Jun 03 '16 at 15:51
  • That looks like a Card View. Many "for pay" control suites have them. Here is a stack overflow answer on how to turn a list view into a card view: http://stackoverflow.com/a/554972/16241 – Vaccano Jun 03 '16 at 14:29

1 Answers1

3

I got curious about this, so did a quick proof of concept of one way to get it done.

enter image description here

I used an ItemsControl bound to a collection of items.

The ItemsPanelTemplate is a WrapPanel, and the ItemTemplate is a custom template. There is also a DataTrigger to change the Template of the last item to be a borderless TextBox for text entry.

<Grid>
    <TextBox IsHitTestVisible="False" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" /> <!-- For Border -->
    <ItemsControl ItemsSource="{Binding Values}" Margin="4">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ContentControl Content="{Binding}">
                    <ContentControl.Style>
                        <Style TargetType="{x:Type ContentControl}">
                            <Setter Property="ContentTemplate">
                                <Setter.Value>
                                    <DataTemplate>
                                        <Border BorderBrush="Gray" BorderThickness="1" CornerRadius="4" Padding="4">
                                            <TextBlock Text="{Binding SomeString}" />
                                        </Border>
                                    </DataTemplate>
                                </Setter.Value>
                            </Setter>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding Value}" Value="0">
                                    <Setter Property="ContentTemplate">
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBox Text="{Binding SomeString}" BorderThickness="0" Padding="5" Width="50" />
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </ContentControl.Style>
                </ContentControl>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

It should be pretty easy to take something like this and add extra functionality :

  • ItemTemplate can be updated to look like what you have. I am guessing an IValueConverter is used to convert the Text value into a Color for the bar along the bottom

  • X button on the ItemTemplate can be bound to an ICommand to remove an item from the list, and can bind the current object as the CommandParameter to know which item to remove.

  • A PropertyChange notification can be used when TextBox is changed to signal that it should flip a switch to make the last item in the list a "saved" item, and add another "new" item for the TextBox binding.

Overall, shouldn't be too hard to achieve what you're looking for.

And this is one of the reasons why I love working with WPF! Can make almost any control I want with ease. :D

Rachel
  • 130,264
  • 66
  • 304
  • 490