How to improve behavior of text box of shape bound to view model for text editing

3 posts, 1 answers
  1. Michael
    Michael avatar
    26 posts
    Member since:
    Oct 2014

    Posted 02 Jan 2015 Link to this post

    Hello,

    Hello,

    I have a diagram bound to a collection of view models that inherit from NodeViewModelBase and LinkViewModelBase<T>.  I've enabled a RadDiagramToolbox so that the user can drag shapes onto the diagram and edit the text in those shapes.  But, I've noticed the following behavior.  When  a shape is bound to a view model and a data template is used for two-way data binding of a text field on the view model, the default behavior of the text box on the shape is different than if the shape was not bound to a view model.

    Using the demo application, when a shape is dragged to the diagram and the user double clicks the shape to activate the edit mode, the text box displays the following behavior:
    - Focus:  the text box has focus so the user can immediately start entering text.
    - Width:  matches the width of the shape
    - Borders:  borders are dashed lines
    - Example: ShapeUnboundTextAction.png
        
    For a shape bound to a view model when it is dropped onto the diagram, the text box displays the following behavior (the data template is shown below):
    - Focus:  The text box does not have focus, so after double clicking the user must then click in the text box to establish focus befor entering text
    - Width: does not match the width of the shape
    - Borders:  I can manipulate the border width (set to 0 in the image), but how to create a dashed-line?
    - Example: ShapeBoundTextAction.png
        
    How do I create a data template and/or style template so that the text box behavior of a shape that is bound to a view model behaves like that of a shape not bound?  If all the behavior cannot be re-created, then in terms of priority I'd like to match behaviors for Focus, Width, then Borders.

    Thanks,

    Mike


    Below are the data templates, style template, and view model I am using.  

    <!-- Non-edit data template -->
    <DataTemplate x:Key="annotationTemplate">
      <TextBlock Text="{Binding Label, Mode=TwoWay}"
                 TextWrapping="Wrap"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="{Binding FontAlignment}"
                 FontFamily="{Binding FontName, Converter={StaticResource nameToFontFamiltyConverter}}"
                 FontStyle="{Binding FontStyle}"
                 FontWeight="{Binding FontWeight}"
                 FontSize="{Binding FontSize}"
                 TextDecorations="{Binding IsFontUnderlined, Converter={StaticResource boolToUnderlinedConverter}}" />
    </DataTemplate>
     
    <!-- Edit data template -->
    <DataTemplate x:Key="annotationEditTemplate">
      <Grid VerticalAlignment="Stretch"
            HorizontalAlignment="Stretch">
        <TextBox Text="{Binding Label, Mode=TwoWay}"
                 TextWrapping="Wrap"
                 AcceptsReturn="True"
                 VerticalScrollBarVisibility="Auto"
                 HorizontalScrollBarVisibility="Auto"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="{Binding FontAlignment, Mode=TwoWay}"
                 FontFamily="{Binding FontName, Mode=TwoWay, Converter={StaticResource nameToFontFamiltyConverter}}"
                 FontStyle="{Binding FontStyle, Mode=TwoWay}"
                 FontWeight="{Binding FontWeight, Mode=TwoWay}"
                 FontSize="{Binding FontSize, Mode=TwoWay}"
                 BorderThickness="0" />
      </Grid>
    </DataTemplate>

    Style Template:
    <Style TargetType="telerik:RadDiagramShape">
      <Setter Property="Background"
              Value="CornflowerBlue" />
      <Setter Property="BorderBrush"
              Value="DarkSlateBlue" />
    </Style>

    View Model:
    public class ColorViewModel : NodeViewModelBase
    {   
      protected string mLabel;
      protected Guid mId;
      protected Color mBackgroundColor;
      protected Color mForegroundColor;
      protected Color mBorderColor;
      protected double mBorderThickness;
      private string mFontName;
      private double mFontSize;
      private FontStyle mFontStyle;
      private FontWeight mFontWeight;
      private HorizontalAlignment mFontAlignment;
      private bool mIsFontUnderlined;
     
      public ColorViewModel()
      {
        IsContentEditable = true;
     
        //Defaults
        BackgroundColor = Colors.LightGray;
        ForegroundColor = Colors.Black;
        BorderColor = Colors.DarkGray;
        BorderThickness = 1;
        FontName = "Arial";
        FontSize = 10;
        FontStyle = FontStyles.Normal;
        FontWeight = FontWeights.Normal;
        FontAlignment = HorizontalAlignment.Left;
        IsFontUnderlined = false;
      }
      public string Label
      {
        get{return mLabel; }
        set
        {
          if (mLabel != value)
          {
            mLabel = value;
            OnPropertyChanged("Label");
          }
        }
      }
     
      public Guid Id
      {
        get {return mId; }
        set
        {
          if (mId != value)
          {
            mId = value;
            OnPropertyChanged("Id");
          }
        }
      }
      public Color BackgroundColor
      {
        get {return mBackgroundColor; }
        set
        {
          if (mBackgroundColor != value)
          {
            mBackgroundColor = value;
            OnPropertyChanged("BackgroundColor");
          }
        }
      }
      public Color ForegroundColor
      {
        get {return mForegroundColor;}
        set
        {
          if (mForegroundColor != value)
          {
            mForegroundColor = value;
            OnPropertyChanged("ForegroundColor");
          }
        }
      }
      public Color BorderColor
      {
        get  { return mBorderColor;   }
        set
        {
          if (mBorderColor != value)
          {
            mBorderColor = value;
            OnPropertyChanged("BorderColor");
          }
        }
      }
      public double BorderThickness
      {
        get  return mBorderThickness;   }
        set
        {
          if (mBorderThickness != value)
          {
            mBorderThickness = value;
            OnPropertyChanged("BorderThickness");
          }
        }
      }
     
      public string FontName
      {
        get    {    return mFontName;   }
        set
        {
          if (mFontName != value)
          {
            mFontName = value;
            OnPropertyChanged("FontName");
          }
        }
      }
      public double FontSize
      {
        get   return mFontSize;  }
        set
        {
          if (mFontSize != value)
          {
            mFontSize = value;
            OnPropertyChanged("FontSize");
          }
        }
      }
      public FontStyle FontStyle
      {
        get { return mFontStyle;  }
        set
        {
          if (mFontStyle != value)
          {
            mFontStyle = value;
            OnPropertyChanged("FontStyle");
          }
        }
      }
      public FontWeight FontWeight
      {
        get { return mFontWeight; }
        set
        {
          if (mFontWeight != value)
          {
            mFontWeight = value;
            OnPropertyChanged("FontWeight");
          }
        }
      }
      public HorizontalAlignment FontAlignment
      {
        get { return mFontAlignment; }
        set
        {
          if (mFontAlignment != value)
          {
            mFontAlignment = value;
            OnPropertyChanged("FontAlignment");
          }
        }
      }
      public bool IsFontUnderlined
      {
        get  { return mIsFontUnderlined;  }
        set
        {
          if (mIsFontUnderlined != value)
          {
            mIsFontUnderlined = value;
            OnPropertyChanged("IsFontUnderlined"); }
        }
      }
     
      // Non-observable
      public bool IsContentEditable { get; set; }
    }












  2. Answer
    Martin
    Admin
    Martin avatar
    1101 posts

    Posted 05 Jan 2015 Link to this post

    Hello Michael,

    Thank you for the attachments and the description.

    When the GraphSource of the diagram is not populated, the edit mode of the shapes works with a default TextBox placed in the shape's template. The diagram implements logic that uses this TextBox for achieving the current default editing look and feel. Also there is a custom style applied on the text element.

    On the other hand when you populate the GraphSource (data binding scenario) the default TextBox is hidden and instead of it there is a ContentPresenter that represents the editing content. Therefore most of the default editing functionality is lost.  However, you can achieve it with custom implementation:
    • For example, you can use an attached property to focus the TextBox in the EditTemplate of the shape. Basically, you can set the focus on the TextBox in the property changed callback of the attached property.
    • You can find the custom style for the edit text box in the ResourceDictionary with the styles for the diagram (Telerik.Windows.Controls.Diagrams.xaml). The style is defined with x:Key set to "EditTextBoxStyle".
    • The custom style for the edit box defines a custom control template which contains a Rectangle element used for a dashed border. There is defined also the stretching of text box's width.

    For your convenience I attached a sample project demonstrating such implementation. Please give the solution a try and let me know if it works for you.

    Regards,
    Martin
    Telerik
     

    Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

     
  3. DevCraft banner
  4. Michael
    Michael avatar
    26 posts
    Member since:
    Oct 2014

    Posted 05 Jan 2015 Link to this post

    Martin,

    Thanks for the quick turn around, the sample code is just what I need to move forward.

    Mike
Back to Top