Welcome to the Xceed Community | Help
Community Search  
More Search Options

Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

Sort Posts: Previous Next
  •  03-30-2010, 6:26 PM Post no. 26346

    Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    I have a ForeignKeyConfiguration applied to a column on a grid.  When a row is edited or a new row is inserted, the grid automatically generates a drop-down box that maps the displayed values to the underlying values.

    My ForeignKeyConfiguration includes a value that I do not wish to appear in the drop-down box, but I wish it to be present in the ForeignKeyConfiguration.ItemsSource.  The reason for this is so that when a new item is created for the insertion row, the property initialises to a default value that has a particular foreign key mapping, but this is not selectable from the drop-down.

    I have attached an example project showing the situation.  There is a foreign key that maps int.MinValue to "Select...", but I wish this to be removed from the drop-down box when editing or inserting despite new items being initialised to int.MinValue (so that "Select..." appears in the insertion row DataCell prior to the cell being edited).

    How can I achieve what I'm after without overriding CellEditor.EditTemplate?  Is there some way to hook into the DropDownOpened event of the automatically created ComboBox perhaps?


    Associate, .NET Development
    Morgan Stanley, UK
  •  04-01-2010, 2:37 PM Post no. 26376 in reply to 26346

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Jason,

    You can't dynamically remove items from that list. I would instead suggest that you don't include the "Select..." in your list and instead modify the DataTemplate to display "Select..." when the value of the DataContext is int.MinValue.

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  04-01-2010, 9:00 PM Post no. 26380 in reply to 26376

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Diane,

    I'm sorry, I have no idea how to do this and I can't find any information on the forums.  I assume this is using a CellContentTemplate and then apply some sort of conditional DataTrigger.  But, I have only ever done this with Style Setters, I'm not sure how to do it with DataContext on a Column so that a string ("Select...") is shown when DataContext is int.MinValue.

    I have started with the following:

    <xcdg:Column FieldName="MyID">
      <xcdg:Column.CellContentTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Path=DataContext}" />
        </DataTemplate>
      </xcdg:Column.CellContentTemplate>
    </xcdg:Column>

    How do I change or add to this so that it displays "Select..." when DataContext=int.MinValue?  And, bear in mind, I wish the drop-down on the column when in edit mode to still contain all the values of the ForeignKeyConfiguration.

    Thanks,

    Jason


    Associate, .NET Development
    Morgan Stanley, UK
  •  04-06-2010, 3:00 PM Post no. 26411 in reply to 26380

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Jason,

    Here is a code snippet I tested out. You will want to adjust it to fit your needs, but it should get you started.

       <!-- Converter that returns True if value received is equal to int.MinValue -->
       <local:IntToBooleanConverter x:Key="myConverter" />

       <!-- Template to use in the custom trigger -->
       <DataTemplate x:Key="myCustomText">
          <TextBlock Text="Select..." />
       </DataTemplate>

       <Style TargetType="{x:Type xcdg:DataCell}">
          <Style.Triggers>
             <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                   <!-- 1st condition : Style only applies to MyID column -->
                   <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=FieldName}"
                                    Value="MyID" />
                   <!-- 2nd condition : Check value of MyID's content -->
                   <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Content, Converter={StaticResource myConverter}}"
                                    Value="True" />
                   <!-- Extra Info: How to verify content of another column
                   <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type xcdg:DataRow}}, Path=DataContext.ColName}"
                                    Value="Test" />
                   -->
                   </MultiDataTrigger.Conditions>
                <Setter Property="ContentTemplate" Value="{StaticResource myCustomText}" />
             </MultiDataTrigger>
          </Style.Triggers>
       </Style>

       public class IntToBooleanConverter : IValueConverter
       {
          public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
          {
             return value is int && ( int )value == int.MinValue;
          }
          public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
          {
             throw new NotImplementedException();
          }
       }

    For other examples, I recommend doing a quick search in the forums on the word "MultiDataTrigger", or any other word that relates to a Style with Triggers that may or may not use a Converter.

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  04-13-2010, 3:07 PM Post no. 26481 in reply to 26411

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Thanks Diane.  This helped.  I modified your solution slightly to work with an InsertionCell rather than DataCell and Int32.MinValue can be accessed without using a converter:

    <DataTemplate x:Key="selectText">
      <TextBlock Text="Select..." />
    </DataTemplate>

    <Style TargetType="{x:Type xcdg:InsertionCell}">
      <Style.Triggers>
        <MultiDataTrigger>
          <MultiDataTrigger.Conditions>
            <!-- 1st condition : Style only applies to MyID column -->
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=FieldName}" Value="MyID" />
            <!-- 2nd condition : Check value of MyID's content -->
            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=Content}" Value="{x:Static sys:Int32.MinValue}" />
          </MultiDataTrigger.Conditions>
          <Setter Property="ContentTemplate" Value="{StaticResource selectText}" />
        </MultiDataTrigger>
      </Style.Triggers>
    </Style>

    However, although this now shows "Select..." in the InsertionCell, it doesn't show it in the combo box "text editor" part when the InsertionCell enters edit mode.  I don't want it to appear in the drop-down, but it would be good if I can get it to display in the "text editor" part.  Is this possible?


    Associate, .NET Development
    Morgan Stanley, UK
  •  04-20-2010, 11:11 AM Post no. 26553 in reply to 26481

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Jason,

    After several attempts by the developer, he only found one way of adding a text in the case that nothing is selected, and that is by using an Adorner.

    For example:

       public class MustSelectAddorner : Adorner
       {
          public MustSelectAddorner( ComboBox adornedElement )
            : base( adornedElement )
          {
             adornedElement.SelectionChanged += new SelectionChangedEventHandler( adornedElement_SelectionChanged );
             TextBlock textBlock = new TextBlock()
             {
                Text = "Select..."
             };
             m_content = textBlock;
          }

          void adornedElement_SelectionChanged( object sender, SelectionChangedEventArgs e )
          {
             this.InvalidateMeasure();
          }

          protected override Size ArrangeOverride( Size finalSize )
          {
             m_content.Arrange( new Rect( finalSize ) );
             return finalSize;
          }

          protected override Size MeasureOverride( Size constraint )
          {
             if( ( ( ComboBox )this.AdornedElement ).SelectedItem != null )
                return Size.Empty;

             m_content.Measure( constraint );
             return m_content.DesiredSize;
          }

          protected override Visual GetVisualChild( int index )
          {
             return m_content;
          }

          protected override int VisualChildrenCount
          {
             get
             {
                return 1;
             }
          }

          public override GeneralTransform GetDesiredTransform( GeneralTransform transform )
          {
             Size gridRenderSize = this.AdornedElement.RenderSize;
             Size contentDesiredSize = m_content.DesiredSize;
             GeneralTransformGroup result = new GeneralTransformGroup();
             result.Children.Add( base.GetDesiredTransform( transform ) );
             result.Children.Add( new TranslateTransform( 4, 4 ) );
             return result;
          }
          private UIElement m_content;
       }

       // And we assign it to the ComboBox during it's Loaded event
       private void comboBox1_Loaded( object sender, RoutedEventArgs e )
       {
          AdornerLayer.GetAdornerLayer( comboBox1 ).Add( new MustSelectAddorner( comboBox1 ) );
       }

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  04-20-2010, 3:25 PM Post no. 26560 in reply to 26553

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    OK, that's good, but there's one problem - how do I hook into the Loaded event of a combo box that doesn't exist until the insertion cell enters edit mode?  Like I mentioned previously, bear in mind that this is a combo box automatically created by the grid due to a foreign key configuration applied to the column...
    Associate, .NET Development
    Morgan Stanley, UK
  •  04-22-2010, 12:21 PM Post no. 26584 in reply to 26560

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Jason,

    You would need to set a ComboBox in the CellEditor and hook to the Loaded event from there. Unfortunately while trying to make an example I found out that the default ForeignKey ComboBox isn't public.

    However the developer found the following workaround by making your own ComboBox template:

       <!-- Resources -->
       <xcdg:NullToBooleanConverter x:Key="nullToBooleanConverter" />

       <xcdg:CellEditor x:Key="fkCellEditor">
          <xcdg:CellEditor.EditTemplate>
             <DataTemplate>
                <ComboBox x:Name="fkComboBox"
                          xcdg:Cell.IsCellFocusScope="True"
                          BorderThickness="0"
                          ItemTemplate="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ParentColumn.CellContentTemplate, Mode=OneWay}"
                          ItemContainerStyle="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.ItemContainerStyle, Mode=OneWay}"
                          ItemsSource="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.ItemsSource, Mode=OneWay}"
                          SelectedValuePath="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.ValuePath, Mode=OneWay}"
                          DisplayMemberPath="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.DisplayMemberPath, Mode=OneWay}"
                          SelectedValue="{xcdg:CellEditorBinding}"
                          Loaded="fkComboBox_Loaded" />

                <!-- Only affect Selector if Template or Style is null -->
                <DataTemplate.Triggers>
                   <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ParentColumn.CellContentTemplate, Converter={StaticResource nullToBooleanConverter}, Mode=OneWay}"
                                Value="True">
                      <Setter TargetName="fkComboBox"
                              Property="ItemTemplateSelector"
                              Value="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ParentColumn.CellContentTemplateSelector, Mode=OneWay}" />
                   </DataTrigger>

                   <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.ItemContainerStyle, Converter={StaticResource nullToBooleanConverter}, Mode=OneWay}"
                                Value="True">
                      <Setter TargetName="fkComboBox"
                              Property="ItemContainerStyleSelector"
                              Value="{Binding RelativeSource={RelativeSource Self}, Path=(xcdg:Cell.CellEditorContext).ForeignKeyConfiguration.ItemContainerStyleSelector, Mode=OneWay}" />
                   </DataTrigger>
                </DataTemplate.Triggers>
             </DataTemplate>
          </xcdg:CellEditor.EditTemplate>
       </xcdg:CellEditor>

       <!-- DataGridControl -->
       <xcdg:DataGridControl.Columns>
          <xcdg:Column FieldName="MyValue"
                       CellEditor="{StaticResource fkCellEditor}" />
       </xcdg:DataGridControl.Columns>

       // Code-behind
       private void fkComboBox_Loaded( object sender, RoutedEventArgs e )
       {
          ComboBox fkCombo = sender as ComboBox;
          AdornerLayer.GetAdornerLayer( fkCombo ).Add( new MustSelectAddorner( fkCombo ) );
       }

       // Remove the following line from your code:
       //map.Add( int.MinValue, "Select..." );

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
  •  05-06-2010, 6:39 AM Post no. 26741 in reply to 26584

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Thanks for working on this and thanks for the reply.  This appears to be a good solution - however, I note that you mentioned that this solution is in lieu of the default ForeignKey ComboBox not being public.  Is this to be resolved?  If so, then I am prepared to wait until that is resolved then I can implement a more elegant solution using the existing ForeignKey ComboBox and the Loaded event thereof in order to attach the Adorner to it.

    Please let me know if this is to be raised as it would be a desirable feature request.

    Many thanks,

    Jason


    Associate, .NET Development
    Morgan Stanley, UK
  •  05-06-2010, 4:25 PM Post no. 26750 in reply to 26741

    Re: Remove items from automatically created ComboBox of a Column with a ForeignKeyConfiguration set

    Hi Jason,

    A feature request was submitted for this, but I haven't received confirmation yet as to when this will be done. I will update this forum thread when I have more information. Thank you for your patience.

     


    ** Quick Tip: Clients with an active support subscription should be sending their questions by email if they wish to benefit from the faster response time. Thanks!


    Diane Lafontaine
    Technical Support
    Xceed Software Inc.
View as RSS news feed in XML
Contact | Site Map | Reviews | Legal Terms of Use | Trademarks | Privacy Statement Copyright 2011 Xceed Software Inc.