This is a migrated thread and some comments may be shown as answers.

DataFormDataField Multiline Comments Box w/ Wrap and Accept Return

2 Answers 177 Views
DataForm
This is a migrated thread and some comments may be shown as answers.
Mike
Top achievements
Rank 1
Mike asked on 14 Apr 2017, 03:27 PM

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 Answers, 1 is accepted

Sort by
0
Dilyan Traykov
Telerik team
answered on 19 Apr 2017, 10:23 AM
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.
0
Mike
Top achievements
Rank 1
answered on 20 Apr 2017, 02:10 PM

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();
}
Tags
DataForm
Asked by
Mike
Top achievements
Rank 1
Answers by
Dilyan Traykov
Telerik team
Mike
Top achievements
Rank 1
Share this question
or