0

I have a DataGrid and when someone clicks on a DataGridCell I want values to overlay that cell. What is the best way to do about this? Adornlayer? Custom Control?

Below is an example. Someone clicks on 17.27 of a DataGrid and I want to have the ranges of the price next to it. The user can then choose a value and set the DataGridCell with the new price. A twist is that the values are next to, not a drop down or I can just use a ComboBox.

enter image description here

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
kay00
  • 327
  • 1
  • 5
  • 16
  • What is your current code like? What have you tried? – Oren Hizkiya Mar 28 '14 at 19:28
  • I just learned about adornerlayer and wondering if I am over thinking this. This just seem complicated http://stackoverflow.com/questions/5595243/in-wpf-how-to-display-adornerlayer-on-top-of-datagrid I was going to do dropdown, but my user says he wants the prices to the right of the selected cell. – kay00 Mar 28 '14 at 19:50

2 Answers2

2

It seems to me for you will fit this controls:


enter image description here

For the ComboBox you can set the dynamic range, being attached to the collection. In DataGrid you can do yourself the ComboBox using DataGridTemplateColumn column:

<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=CustomObjectStringMember}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>

    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <ComboBox ItemsSource="{Binding Path=CustomObjectListMember}"
                      Text="{Binding Path=CustomObjectStringMember}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

Or usingDataGridComboBoxColumn:

<DataGridComboBoxColumn Header="Current Category"
                        SelectedValueBinding="{Binding Path=CurrentCategory}"
                        SelectedValuePath="CategoryID"
                        DisplayMemberPath="CategoryName"
                        ItemsSource="{Binding Source={StaticResource categoriesDataProvider}}" />

enter image description here

IntegerUpDown provides a TextBox with button spinners that allow incrementing and decrementing Nullable values by using the spinner buttons.


Try using Popup with ListBox like this:

<Popup Name="MyPopUp"
       UseLayoutRounding="True"
       AllowsTransparency="False"
       IsOpen="True"
       Placement="Right">

    <Border Name="BorderContent" 
            UseLayoutRounding="True"
            Width="140"
            BorderThickness="1"
            BorderBrush="Black">

        <StackPanel Background="White">
            <TextBlock Background="White" 
                       Foreground="Black"
                       HorizontalAlignment="Center"
                       Text="MARKET" />

            <Separator Background="Black" Height="2" />

            <ListBox BorderBrush="Transparent">
                <ListBoxItem>17.27</ListBoxItem>
                <ListBoxItem>17.28</ListBoxItem>
                <ListBoxItem>17.29</ListBoxItem>
                <ListBoxItem>17.30</ListBoxItem>
            </ListBox>
        </StackPanel>
    </Border>
</Popup>       

Output

enter image description here

For Popup you can set Placement to Right and use dynamic collection for ItemSource. To appear the Popup in the DataGrid you need place it in the CellEditingTemplate like this:

<DataGridTemplateColumn Header="Test">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Sample}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>

    <DataGridTemplateColumn.CellEditingTemplate>
        <DataTemplate>
            <Grid>
                <TextBox Text="{Binding Path=Sample}" />
                <Popup ... />
            </Grid>
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68
  • This would work, but my users want the box next to the item, not as a drop down. – kay00 Mar 28 '14 at 19:46
  • Error: DataTemplate already has a child and cannot add popup datatemplate – kay00 Mar 28 '14 at 20:37
  • 1
    @kay00: Add panel in DataTemplate: ``. See my example carefully. – Anatoliy Nikolaev Mar 28 '14 at 20:42
  • Popup won't show up when there's binding. For example Text="{Binding Path=Sample}" needs to be replaced with Text=Foo. Also when I choose a value it doesn't set that value for the cell. It is highlighted though. – kay00 Apr 01 '14 at 14:47
  • My mistake. The popup does show up. But how do I set the value of the cell once I choose a value? – kay00 Apr 01 '14 at 15:49
  • @kay00: First, you need to necessarily to bind a `SelectedItem` property to ListBox, to know which item has been selected. Second, try using [`x:Reference`](http://msdn.microsoft.com/en-us/library/ee795380(v=vs.110).aspx) for Binding like this (TextBlock in ` --> `): ``. – Anatoliy Nikolaev Apr 02 '14 at 04:18
  • I think the problem is the popup list doesn't know about the datacontext ---> System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedItem' property not found on 'object' ''String' (HashCode=277915782)'. BindingExpression:Path=SelectedItem; DataItem='String' (HashCode=277915782); target element is 'ListBox' (Name=''); target property is 'SelectedItem' (type 'Object') – kay00 Apr 02 '14 at 20:55
  • i'll run snoop to see what is going on – kay00 Apr 02 '14 at 21:08
0

I think Popup is probably best for this.

Michael Gunter
  • 12,528
  • 1
  • 24
  • 58