DataFormDataField Multiline Comments Box w/ Wrap and Accept Return

3 posts, 0 answers
  1. Mike
    Mike avatar
    5 posts
    Member since:
    Mar 2017

    Posted 14 Apr Link to this post

    Hi. Im trying to create a DataFormDataField for comments. The requirements are that the textbox needs to accept return, wrap and always show 3 lines no matter the ammount of text.

     

    my first attempt i came up with the following

     

                                    <telerik:DataFormDataField x:Name="Comm"
                                                               Label="Comments"
                                                               LabelPosition="Above"
                                                               Width="355"
                                                               Canvas.Left="10"
                                                               Canvas.Top="61">
                                        <TextBox Height="50"
                                                 AcceptsReturn="True"
                                                 TextWrapping="Wrap"
                                                 Text="{Binding BIGCOMMENTS, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                                 IsReadOnly="{Binding IsReadOnly, ElementName=Comm, Mode=OneWay}"
                                                 VerticalContentAlignment="Top"
                                                 TabIndex="18" />
                                    </telerik:DataFormDataField>

     

    works nice until you need to resize, it gets a bit wonky. second attempt was to modify the template in blend.

     

      <ControlTemplate x:Key="WBDataFormMultiLineDataField"
                         TargetType="{x:Type telerik:DataFormDataField}">
            <Border x:Name="PART_RootElement"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Background="{TemplateBinding Background}"
                    CornerRadius="{DynamicResource {x:Static telerik:Office2016ResourceKey.CornerRadius}}"
                    UseLayoutRounding="True">
                <Grid x:Name="PART_DataFormDataFieldGrid"
                      Margin="{TemplateBinding Padding}">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*" />
                        <ColumnDefinition Width="2*" />
                        <ColumnDefinition Width="24" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="*" />
                    </Grid.RowDefinitions>
                    <ContentControl x:Name="PART_Label"
                                    ContentTemplate="{TemplateBinding LabelTemplate}"
                                    Content="{TemplateBinding Label}"
                                    Foreground="{TemplateBinding Foreground}"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    IsTabStop="False"
                                    Margin="4,0"
                                    VerticalAlignment="Center"
                                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
                    <TextBox x:Name="PART_ContentPresenter"
                             Grid.Column="1"
                             HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                             Grid.Row="1"
                             Text="{Binding DataMemberBinding, RelativeSource={RelativeSource TemplatedParent}}"
                             VerticalAlignment="Stretch"
                             AcceptsReturn="True"
                             TextWrapping="Wrap"
                             VerticalContentAlignment="Top"
                             TabIndex="18" />

                    <Grid x:Name="DescriptionIcon"
                          Background="Transparent"
                          Grid.Column="2"
                          HorizontalAlignment="Center"
                          Margin="4,0,0,0"
                          Grid.Row="1"
                          VerticalAlignment="Center">
                        <Grid.ToolTip>
                            <ToolTip Content="{TemplateBinding Description}" />
                        </Grid.ToolTip>
                        <Grid.Visibility>
                            <Binding Path="Description"
                                     RelativeSource="{RelativeSource TemplatedParent}">
                                <Binding.Converter>
                                    <dataForm:DescriptionVisibilityConverter />
                                </Binding.Converter>
                            </Binding>
                        </Grid.Visibility>
                        <TextBlock Foreground="{DynamicResource {x:Static telerik:Office2016ResourceKey.IconBrush}}"
                                   FontWeight="Normal"
                                   FontStyle="Normal"
                                   FontSize="16"
                                   FontFamily="/Telerik.Windows.Controls;component/Themes/Fonts/TelerikWebUI.ttf#TelerikWebUI"
                                   HorizontalAlignment="Center"
                                   Margin="1,0,0,0"
                                   Text="&#xE402;"
                                   VerticalAlignment="Center"><Run Text="&#xE402;" /></TextBlock>
                    </Grid>
                </Grid>
            </Border>
        </ControlTemplate>

     

    I basically replaced the content presenter (which was showing a text box) with an acutal textbox. this works much better in terms of resizing, however i lose functionality for 'DataMemberBinding', which i need.

     

    Any ideas to an ideal solution?

  2. Dilyan Traykov
    Admin
    Dilyan Traykov avatar
    603 posts

    Posted 19 Apr Link to this post

    Hello Mike,

    The suggested approach in this scenario would be to define a custom data field as demonstrated in this article.

    public class CustomCommentField : DataFormDataField
    {
        protected override DependencyProperty GetControlBindingProperty()
        {
            return TextBox.TextProperty;
        }
        protected override Control GetControl()
        {
            DependencyProperty dependencyProperty = this.GetControlBindingProperty();
            var textBox = new TextBox();
            textBox.AcceptsReturn = true;
            textBox.MaxLines = 3;
            textBox.TextWrapping = TextWrapping.Wrap;
            if (this.DataMemberBinding != null)
            {
                var binding = this.DataMemberBinding;
                textBox.SetBinding(dependencyProperty, binding);
            }
            textBox.SetBinding(TextBox.IsEnabledProperty, new Binding("IsReadOnly") { Source = this, Converter = new InvertedBooleanConverter() });
            return textBox;
        }
    }

    You will probably also need to handle the enter key by creating a custom keyboard command provider by using the approach suggested by my colleague in this thread.

    public override List<DelegateCommandWrapper> ProvideCommandsForKey(KeyEventArgs args)
    {
        List<DelegateCommandWrapper> actionsToExecute = base.ProvideCommandsForKey(args);
     
        if (args.Key == Key.Enter)
        {
            if (args.OriginalSource is TextBox && (args.OriginalSource as TextBox).AcceptsReturn)
            {
                TextBox TB = args.OriginalSource as TextBox;
     
                actionsToExecute.Clear();
                TB.SelectionStart = TB.Text.Length;
                TB.Focus();
            }
            else
            {
                actionsToExecute.Clear();
                actionsToExecute.Add(new DataFormDelegateCommandWrapper(RadDataFormCommands.CommitEdit, this.DataForm));
            }
        }
        if (actionsToExecute.Count > 0)
        {
            actionsToExecute.Add(new DataFormDelegateCommandWrapper(new Action(() => { this.DataForm.AcquireFocus(); }), 100, this.DataForm));
            args.Handled = true;
        }
        return actionsToExecute;
    }

    I hope you find this helpful. Do let me know if you need any further assistance on the matter.

    Regards,
    Dilyan Traykov
    Telerik by Progress
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  3. Mike
    Mike avatar
    5 posts
    Member since:
    Mar 2017

    Posted 20 Apr Link to this post

    with some additional tinkering, i was able to get what i need. thanks for pointing me in the right direction. i also added the following command

    if (args.Key == Key.Escape)
               {
                   if (DataForm.CanCommitEdit)
                   {
                       RadWindow.Confirm("Save Changes?", (s, e) =>
                       {
                           if (e.DialogResult.HasValue && e.DialogResult.Value && DataForm.CanCommitEdit)
                           {
                               DataForm.CommitEdit();
                           }
                           else
                           {
                               DataForm.CancelEdit();
                           }
                       });
                   }
               }

     

              

     

    I can only assume this works better here than in the radWindow OnPreviewClose() method which, ill admit i copied from the erp demo.

    public LeasingDataFormWindow(object type)
    {
        InitializeComponent();
     
        KeyGesture cancelKeyGesture = new KeyGesture(Key.Escape);
        KeyBinding cancelCmdKeybinding = new KeyBinding(WindowCommands.Cancel, cancelKeyGesture);
        InputBindingCollection inputCollection = new InputBindingCollection();
        inputCollection.Add(cancelCmdKeybinding);
        InputBindings.Add(cancelCmdKeybinding);
    }
     
    static LeasingDataFormWindow()
    {
        CommandManager.RegisterClassCommandBinding(typeof(LeasingDataFormWindow), new CommandBinding(WindowCommands.Cancel, OnCancelCommandExecuted));
    }
     
    private static void OnCancelCommandExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        var dialog = sender as LeasingDataFormWindow;
        if (dialog != null)
        {
            dialog.DataForm.CancelEdit();
            dialog.Close();
        }
    }
     
    protected override bool OnPreviewClosed()
    {
        _isClosing = true;
     
        if (DataForm.CanCommitEdit)
        {
            RadWindow.Confirm("Save Changes?", (s, e) =>
            {
                if (e.DialogResult.HasValue && e.DialogResult.Value && DataForm.CanCommitEdit)
                {
                    DataForm.CommitEdit();
                }
                else
                {
                    DataForm.CancelEdit();
                }
            });
        }
        return base.OnPreviewClosed();
    }
Back to Top