Home Forums WPF controls Xceed DataGrid for WPF Combobox column item display different from value

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #26980 |

    I have a combobox column that allows the user to select an item from a drop down. How can I differentiate between what the user sees and the value selected? For example, in the database I want to store “NW”, but I want the user to see “NorthWest”. Is there a way I can have two lists, one that stores the abbreviation and the other the verbose term:

    List<String> shortList = new List<String>();

    shortList.Add(“NW”);

    shortList.Add(“N”);

    List <String> longList = new List<String>();

    longList.Add(“NorthWest”);

    longList.Add(“North”);

     

    The code I use to load my combo boxes looks like this:

                List<String> itemList = new List<String>();
                itemList.Add(“NW”);
                itemList.Add(“N”);
                itemList.Add(“NE”);
                itemList.Add(“E”);
                itemList.Add(“SE”);
                itemList.Add(“S”);
                itemList.Add(“SW”);
                itemList.Add(“W”);

                Binding binding = new Binding();
                binding.Source = itemList;

                FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ComboBox));
                factory.SetValue(ComboBox.ItemsSourceProperty, binding);

       
            Xceed.Wpf.DataGrid.Markup.CellEditorBindingExtension
    cellEditorBindingExtension = new
    Xceed.Wpf.DataGrid.Markup.CellEditorBindingExtension();
                factory.SetValue(ComboBox.SelectedValueProperty, cellEditorBindingExtension.ProvideValue(null) as BindingBase);

                DataTemplate editTemplate = new DataTemplate(typeof(ComboBox));
               
                editTemplate.VisualTree = factory;

                CellEditor cellEditor = new CellEditor();
                cellEditor.EditTemplate = editTemplate;
                dataGridControl.Columns[0].CellEditor = cellEditor;

    I would think I would want to do something like this:

                Binding shortBinding = new Binding();
               
    shortBinding .Source = shortList;

                FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ComboBox));
                factory.SetValue(ComboBox.ItemsSourceProperty,
    shortBinding);

                Binding longBinding = new Binding();
               
    longBinding .Source = longList;


                factory.SetValue(ComboBox.SelectedValueProperty,
    longBinding);
     

    However, if I do that I lose the CellEditorBindingExtension object, which, I believe, makes the whole thing work properly when the user makes a selection from the list. Even if I could store the items in a class which just had a ShortName and a LongName property and I could just specify which property to use for the display and the value, that would work for my purposes.

    What is the best way to accomplish this? 

    Imported from legacy forums. Posted by Mike Pateras (had 2139 views)

    User (Old forums)
    Member
    Post count: 23064

    If you had a class which has a ShortName and LongName property, the following should work:

    List<BindingClass> bindingList = values..

                DataTemplate myEditorTemplate = new DataTemplate();
                myEditorTemplate.VisualTree = new FrameworkElementFactory(typeof(ComboBox));
                myEditorTemplate.VisualTree.SetValue(ComboBox.ItemsSourceProperty, bindingList);
                myEditorTemplate.VisualTree.SetValue(ComboBox.SelectedValuePathProperty, “ShortName”);
                myEditorTemplate.VisualTree.SetValue(ComboBox.DisplayMemberPathProperty, “LongName”);
                CellEditorBindingExtension cellbinding = new CellEditorBindingExtension();
                myEditorTemplate.VisualTree.SetBinding(ComboBox.SelectedValueProperty, (BindingBase)cellbinding.ProvideValue(null));
                CellEditor cellEdit = new CellEditor();
                cellEdit.EditTemplate = myEditorTemplate;

                dataGridControl.Columns[0].CellEditor = cellEditor;

    Hope that helps!

    Cheerios,

    Serene
     

    Imported from legacy forums. Posted by Serene (had 1332 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks, Serene! That worked. The only problem is, when focus isn’t on that field (in other words the user isn’t selecting a new value), the short value (NW) is shown. This wasn’t really covered in the scope of my original question, but is there a way for the field to show the long value even if the user hasn’t initiated a drop-down? I don’t want the user to ever see the short version.

    Thanks again!

     

    EDIT:
    Also, why can’t I mark Serene’s post as the answer? I only have the option to mark this post as the answer.
     

    Imported from legacy forums. Posted by Mike Pateras (had 752 views)

    Xceed Support
    Member
    Post count: 5658

    Hi Mike,

    You will also need to change the CellContentTemplate to display the long value rather than the short. The SolidFoundation sample demonstrates how to do this for the “ShipVia/Shippers” column.

    As for the “Mark as answer” option, I will look into it.

    Imported from legacy forums. Posted by Jenny [Xceed] (had 1112 views)

    User (Old forums)
    Member
    Post count: 23064

    Hmm… I get shown the short value only after I make a selection (which is unfortunately something that I have not yet gotten past [:(])

    But otherwise, the long value is shown by default.

    I vaguely remember having this similar problem with a previous version of the grid though… do you have the latest updated version
     

    Imported from legacy forums. Posted by Serene (had 880 views)

    Xceed Support
    Member
    Post count: 5658

    The latest package can be download here.

    Imported from legacy forums. Posted by Jenny [Xceed] (had 702 views)

    User (Old forums)
    Member
    Post count: 23064

    Thank you for the responses.

    I downloaded the grid less than a week ago, so I’m pretty sure I have the latest version.

    I definitely see the short version unless I’ve made a selection, at which time I see the long version.  Once I move off the row the short value returns.

    I’m sifting through SolidFoundation, but I’m finding it difficult to determine what is going on because of the size of the sample. This is what I’ve found:

          <DataTemplate x:Key=”shipperGroupValueDataTemplate”>
             <local:ShipperIDDictionary Key=”{TemplateBinding Content}”
                                        ContentTemplate=”{StaticResource shipperGroupDataTemplate}”>
             </local:ShipperIDDictionary>
          </DataTemplate>

    I’m really not sure how this is applicable to my problem, but I’m still new to XAML so maybe I’m just missing something. I think once I can figure out what’s going on in XAML (and I’m sure there’s more to it than the above snippet but there’s a ton of XAML in that sample and it’s difficult to find out what everything does), I can start to translate what I need to know to work a solution in code.

    Is there a chance, though, that I can do something similar to what I’ve already done? It looks like both the CellEditor and the CellContentTemplate both take a DataTemplate object. I’ve tried to construct a DataTemplate object for the CellContentTemplate in a manner similar to that of the EditTemplate but I’m not entirely sure what type it should be and what exactly to bind. This is what I’m using for the CellEditor:

                DataTemplate editTemplate = new DataTemplate(typeof(ComboBox));

                Xceed.Wpf.DataGrid.Markup.CellEditorBindingExtension cellEditorBindingExtension = new Xceed.Wpf.DataGrid.Markup.CellEditorBindingExtension();

                editTemplate.VisualTree = new FrameworkElementFactory(typeof(ComboBox));
                editTemplate.VisualTree.SetValue(ComboBox.DisplayMemberPathProperty, “Long”);
                editTemplate.VisualTree.SetValue(ComboBox.ItemsSourceProperty, binding); // Bound to my list of direction items
                editTemplate.VisualTree.SetValue(ComboBox.SelectedValueProperty, cellEditorBindingExtension);
                editTemplate.VisualTree.SetValue(ComboBox.SelectedValuePathProperty, “Short”);

     Can something similar not be done for the CellContentTemplate? I found this in SolidFoundation:

          <DataTemplate x:Key=”shipperDataTemplate”>
             <TextBlock Text=”{Binding CompanyName}”
                        TextTrimming=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}, Path=ParentColumn.TextTrimming}”
                        TextWrapping=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}, Path=ParentColumn.TextWrapping}”/>
          </DataTemplate>

    Should I maybe set my DataTemplate to a TextBlock and then somehow bind its TextProperty to the Long property of my type? I tried doing that, but couldn’t quite get it (as there is no TextPathProperty), but I think I’m still missing some steps so I’m probably not as close as I think.

    Imported from legacy forums. Posted by Mike Pateras (had 5911 views)

    Xceed Support
    Member
    Post count: 5658

    The main issue in this scenario is that there is no SelectedValuePath/ItemsSource equivalent for the TextBlock that is used as the CellContentTemplate. In the SolidFoundation sample, a DataTable dictionary was created to workaround this problem. The DataTableDictionary and ShipperIDDictionary classes are there for that reason. That said, add them both to your project and define you CellContentTemplate in the following manner (I have simplified the code from the SolidFoundation sample)

       <Grid xmlns:xcdg=”http://schemas.xceed.com/wpf/xaml/datagrid“>
          <Grid.Resources>
             <xcdg:DataGridCollectionViewSource x:Key=”cvs_orders”
                                                Source=”{Binding Source={x:Static Application.Current},
                                                             Path=Orders}” />
          </Grid.Resources>

          <xcdg:DataGridControl x:Name=”OrdersGrid”
                                ItemsSource=”{Binding Source={StaticResource cvs_orders}}”>
             <xcdg:DataGridControl.Columns>
                <xcdg:Column FieldName=”ShipVia”>
                   <xcdg:Column.CellContentTemplate>
                      <DataTemplate>
                         <local:ShipperIDDictionary Key=”{TemplateBinding Content}”
                                                    MinHeight=”22″>
                            <local:ShipperIDDictionary.ContentTemplate>
                               <DataTemplate>
                                  <TextBlock Text=”{Binding CompanyName}” />
                               </DataTemplate>
                            </local:ShipperIDDictionary.ContentTemplate>
                         </local:ShipperIDDictionary>
                      </DataTemplate>
                   </xcdg:Column.CellContentTemplate>
                   <xcdg:Column.CellEditor>
                      <xcdg:CellEditor>
                         <xcdg:CellEditor.EditTemplate>
                            <DataTemplate>
                               <ComboBox BorderThickness=”0″
                                         Background=”Transparent”
                                         Foreground=”{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(TextElement.Foreground)}”
                                         MinHeight=”22″
                                         VerticalContentAlignment=”Top”
                                         SelectedValuePath=”ShipperID”
                                         ItemsSource=”{Binding Source={x:Static Application.Current},Path=Shippers}”
                                         SelectedValue=”{xcdg:CellEditorBinding}”>
                                  <ComboBox.ItemTemplate>
                                     <DataTemplate>
                                        <TextBlock Text=”{Binding Path=CompanyName}” />
                                     </DataTemplate>
                                  </ComboBox.ItemTemplate>
                                  <ComboBox.Resources>
                                     <Style TargetType=”Popup”>
                                        <Setter Property=”TextElement.Foreground”
                                                Value=”{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}” />
                                     </Style>
                                  </ComboBox.Resources>
                               </ComboBox>
                            </DataTemplate>
                         </xcdg:CellEditor.EditTemplate>
                         <xcdg:CellEditor.ActivationGestures>
                            <xcdg:KeyActivationGesture SystemKey=”Down”
                                                       Modifiers=”Alt” />
                            <xcdg:KeyActivationGesture Key=”Up”
                                                       Modifiers=”Alt” />
                            <xcdg:KeyActivationGesture Key=”F4″ />
                            <xcdg:KeyActivationGesture Key=”Space” />
                         </xcdg:CellEditor.ActivationGestures>
                      </xcdg:CellEditor>
                   </xcdg:Column.CellEditor>
                </xcdg:Column>
             </xcdg:DataGridControl.Columns>
          </xcdg:DataGridControl>
       </Grid>

    Imported from legacy forums. Posted by Jenny [Xceed] (had 6531 views)

    User (Old forums)
    Member
    Post count: 23064

    Thank you, Jenny. I appreciate your time.

    Imported from legacy forums. Posted by Mike Pateras (had 623 views)

    Xceed Support
    Member
    Post count: 5658

    Glad I could help [:)]

     

    Imported from legacy forums. Posted by Jenny [Xceed] (had 804 views)

    User (Old forums)
    Member
    Post count: 23064

    I have similar situation except I use observable collection as table data source. I’ve made dictionary with id/value (int/string) pairs which i use as combo box items source. I just don’t know, how to create cell data template to display value and not int (observable collection item id). My column definition in C#:

    DataTemplate template = new DataTemplate();
    FrameworkElementFactory factory = new FrameworkElementFactory(typeof(ComboBox));
    factory.SetValue(ComboBox.ItemsSourceProperty, PList);
    factory.SetValue(ComboBox.DisplayMemberPathProperty, “Value”);
    factory.SetValue(ComboBox.SelectedValuePathProperty, “Key”);
    CellEditorBindingExtension binding = new CellEditorBindingExtension();
    factory.SetValue(ComboBox.SelectedValueProperty, binding);
    template.VisualTree = factory;

    Column column = this.Table.Columns[“payee_id_fk”];
    CellEditor cellEditor = new CellEditor();
    cellEditor.EditTemplate = template;
    column.CellEditor = cellEditor;
    column.CellContentTemplate = this.grid1.FindResource(“payeeCellDataTemplate”) as DataTemplate;
    column.CellEditorDisplayConditions = CellEditorDisplayConditions.MouseOverCell;
    column.Title = “Payee”;

    And xaml part:

    <!–A data template that I want to represent a payee with its name–>
      <DataTemplate x:Key=”payeeCellDataTemplate”>
        <TextBlock Text=”{Binding}”
          TextTrimming=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}, Path=ParentColumn.TextTrimming}”
          TextWrapping=”{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type xcdg:Cell}}, Path=ParentColumn.TextWrapping}”/>
      </DataTemplate>

    When not in editor, the displayed value is int (actualy foreign key). When I enter edit mode (on mouse over), editor (combo box) is displayed exactly as I want. Even when I change value, it is also writen in observable collection (as I want). But when I leave editing, cell displayed value is back on Int.

     My question is, how to change cell data template to show value (text) part of dictionary item when not in edit mode. Is this possible?

     

     

    Imported from legacy forums. Posted by Lojze (had 1306 views)

    User (Old forums)
    Member
    Post count: 23064

    Hi Jenny,

    I am facing a similar issue. I have included a combobox within a grid. The datasource for the combobox is a datatable called Department with a single column called dept.

    After binding when I run the app I am able to see only empty comboboxes, however when i click on the combobox the drop down contains all the values from the backend Department datatable. How do I bind a selected value to all the comboboxes?

    I have included my xaml below, would appreciate any help. Thanks in advance.

     [The section below appears in the resources section of the xaml page]

    <DataTemplate x:Key=”departmentDataTemplate”>
                <TextBlock Text=”{Binding}”/>
            </DataTemplate>
           
            <xcdg:CellEditor x:Key=”departmentEditor”>
                <xcdg:CellEditor.EditTemplate>
                    <DataTemplate>
                        <ComboBox BorderThickness=”0″ Background=”Transparent”
                             Foreground=”{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(TextElement.Foreground)}”
                             VerticalContentAlignment=”Top” MinHeight=”22″
                             ItemsSource=”{Binding Source={x:Static Application.Current},Path=Department}”
                             DisplayMemberPath=”dept” SelectedValue=”{xcdg:CellEditorBindingExtension}”
                             FocusVisualStyle=”{x:Null}” SelectedValuePath=”dept”>
                            <ComboBox.ItemTemplate>
                                <DataTemplate>
                                    <TextBlock Text=”{Binding Path=dept}” />
                                     </DataTemplate>
                            </ComboBox.ItemTemplate>
                            <ComboBox.Resources>
                                <Style TargetType=”Popup”>
                                    <Setter Property=”TextElement.Foreground”
                                    Value=”{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}”/>
                                </Style>
                            </ComboBox.Resources>

                        </ComboBox>
                    </DataTemplate>
                </xcdg:CellEditor.EditTemplate>>
                <xcdg:CellEditor.ActivationGestures>
                    <xcdg:KeyActivationGesture SystemKey=”Down”
                                           Modifiers=”Alt”/>
                    <xcdg:KeyActivationGesture Key=”Up”
                                           Modifiers=”Alt”/>
                    <xcdg:KeyActivationGesture Key=”F4″/>
                    <xcdg:KeyActivationGesture Key=”Space”/>
                </xcdg:CellEditor.ActivationGestures>
            </xcdg:CellEditor>

     [The section below shows the xaml for the grid. The grid actually has 3 other columns from an Employees table, the combobox alone is being bound to a Department table.]

        <DockPanel>
            <xcdg:DataGridControl x:Name=”Grid1″
                                  ItemsSource=”{Binding Source={StaticResource cvsEmployees}}”
                                  AutoCreateDetailConfigurations=”True”
                                  AllowDetailToggle=”True” EditTriggers=”BeginEditCommand, SingleClick, ActivationGesture” CellEditorDisplayConditions=”MouseOverCell”
                                  ItemScrollingBehavior=”Immediate” Width=”Auto”>
                <xcdg:DataGridControl.View>
                    <xcdg:TableView/>
                </xcdg:DataGridControl.View>
                <xcdg:DataGridControl.Columns>
                    <xcdg:Column FieldName=”Department”
                             Title=”Department”
                             Width=”125″
                             CellContentTemplate=”{StaticResource departmentDataTemplate}”
                             CellEditor=”{StaticResource departmentEditor}”
                             Visible=”True” IsMainColumn=”True” />
                </xcdg:DataGridControl.Columns>
            </xcdg:DataGridControl>
        </DockPanel>

     

    Thanks,

    Sidharth

    Imported from legacy forums. Posted by Sidharth (had 1045 views)

    User (Old forums)
    Member
    Post count: 23064

    I haven’t tried it myself, but this sounds like a problem that a ValueConverter addresses. I image using a Binding with a Converter would work. Jenny, do you see problems with that approach?

    Imported from legacy forums. Posted by Hao (had 1810 views)

Viewing 13 posts - 1 through 13 (of 13 total)
  • You must be logged in to reply to this topic.