PopupButton with multililine text box as DataTemplate

Grids for WPF Forum

Posted 10 years ago by Balaram Barange
Version: 4.5.0487
Avatar
Hi Team,

I want to dynamically create DataTemplate for PopupButton with multililine text box.

I want to convert below code

<Window x:Class="DescriptionField.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
    Title="Window1" Height="300" Width="300">
    <Grid x:Name="myGrid">
        <shared:PopupButton Height="25" Width="20" DisplayMode="PopupOnly" PopupHorizontalOffset="-15" PopupVerticalOffset="-25" >
            <shared:PopupButton.PopupContent>
                <TextBox Height="50" TextWrapping="Wrap" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Auto" >This text can be updated as needed and the focus can be moved outside the popup, which will not close until the popup is explicitly closed. Which can be done by clicking the popup indicator again, or clicking the close button above.</TextBox>
            </shared:PopupButton.PopupContent>
        </shared:PopupButton>
    </Grid>
</Window>
in code behind. Please have look at following code. Please suggest what will be the value for PopupContent DP?

private void InitMultiLineTextBox()
        {
            PropertyGridCategoryItem category = new PropertyGridCategoryItem();
            category.DisplayName = "Person Information";
            myGrid.Items.Add(category);

            PropertyGridPropertyItem item = new PropertyGridPropertyItem();
            item.DisplayName = "Name";
            item.Value = "Maulik Gordiya";
            ApplyMultiLineTextBoxDataTemplate(item);
            category.Accessors.Add(item);
        }

        private void ApplyMultiLineTextBoxDataTemplate(PropertyGridPropertyItem propertyGridItem)
        {
            try
            {
                DataTemplate dataTemplate = new DataTemplate(); // DataTemple

                FrameworkElementFactory parentFactory = new FrameworkElementFactory(typeof(Grid));

                FrameworkElementFactory childFactoryTxtBox = new FrameworkElementFactory(typeof(TextBox));
                childFactoryTxtBox.SetBinding(TextBox.TextProperty, new Binding("Value") { RelativeSource = new RelativeSource() { AncestorType = typeof(IPropertyDataAccessor) }, Mode = BindingMode.TwoWay, ValidatesOnExceptions = true, NotifyOnValidationError = true });
                childFactoryTxtBox.SetValue(TextBox.IsReadOnlyProperty, true);
                childFactoryTxtBox.SetValue(TextBox.BorderThicknessProperty, new Thickness(0));
                childFactoryTxtBox.SetBinding(TextBox.IsEnabledProperty, new Binding("IsEnabled") { Source = propertyGridItem });
                childFactoryTxtBox.Name = "childTextBox";

                FrameworkElementFactory popupButtonFactory = new FrameworkElementFactory(typeof(PopupButton));
                popupButtonFactory.SetValue(PopupButton.DisplayModeProperty, PopupButtonDisplayMode.PopupOnly);
                popupButtonFactory.SetValue(PopupButton.WidthProperty, 20.0);
                popupButtonFactory.SetValue(PopupButton.PopupHorizontalOffsetProperty, -15.0);
                popupButtonFactory.SetValue(PopupButton.PopupVerticalOffsetProperty, -25.0);
                popupButtonFactory.Name = "childMultiLineTextBox";

                TextBox tb = new TextBox();
                tb.TextWrapping = TextWrapping.Wrap;
                tb.HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden;
                tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                tb.SetBinding(TextBox.TextProperty, new Binding("Value") { RelativeSource = new RelativeSource() { AncestorType = typeof(IPropertyDataAccessor) } });
                popupButtonFactory.SetValue(PopupButton.PopupContentProperty, tb); // Here exception comes. <i><b>HOW CAN I SET PopupContent?</b></i>
                
                parentFactory.AppendChild(childFactoryTxtBox);
                parentFactory.AppendChild(popupButtonFactory);
                dataTemplate.VisualTree = parentFactory;

                propertyGridItem.ValueTemplate = dataTemplate;
            }
            catch (Exception ex)
            {
            }
        }

Comments (4)

Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Balaram,

You will need to construct another FrameworkElementFactory and DataTemplate for the TextBox used inside the popup. Then set the PopupButton.PopupContentTemplateProperty to that DataTemplate.

You won't be able to set the PopupContent to a UIElement, otherwise it could/would be used in several locations in the visual tree.


Actipro Software Support

Posted 10 years ago by Balaram Barange
Avatar
Thanks for reply.

I have created another FrameworkElementFactory and DataTemplate for the TextBox and set it on PopupButton.PopupContentTemplateProperty. But still the popup window doesn't come. Please have a look on following modified code.

private void InitMultiLineTextBox()
        {
            PropertyGridCategoryItem category = new PropertyGridCategoryItem();
            category.DisplayName = "Person Information";
            myGrid.Items.Add(category);

            PropertyGridPropertyItem item = new PropertyGridPropertyItem();
            item.DisplayName = "Name";
            ApplyMultiLineTextBoxDataTemplate(item);
            category.Accessors.Add(item);
        }

        private void ApplyMultiLineTextBoxDataTemplate(PropertyGridPropertyItem propertyGridItem)
        {
            try
            {
                // Popup Content Template -- Another framework element factory and DataTemplare for TextBoX
                DataTemplate popupDataTemplate = new DataTemplate();
                FrameworkElementFactory popupChildFactoryTxtBox = new FrameworkElementFactory(typeof(TextBox));
                popupDataTemplate.VisualTree = popupChildFactoryTxtBox;
                
                // Popup Button
                FrameworkElementFactory popupButtonFactory = new FrameworkElementFactory(typeof(PopupButton));
                popupButtonFactory.SetValue(PopupButton.DisplayModeProperty, PopupButtonDisplayMode.PopupOnly);
                popupButtonFactory.SetValue(PopupButton.PopupContentTemplateProperty, popupDataTemplate); // Assign Template
                popupButtonFactory.SetValue(PopupButton.HorizontalAlignmentProperty, HorizontalAlignment.Right);
                popupButtonFactory.SetValue(PopupButton.WidthProperty, 20.0);

                DataTemplate dataTemplate = new DataTemplate(); // DataTemple
                dataTemplate.VisualTree = popupButtonFactory;

                // Attach to Value Template
                propertyGridItem.ValueTemplate = dataTemplate;
            }
            catch (Exception ex)
            {
            }
        }
Posted 10 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Balaram,

It looks like there is an issue with using the PopupContentTemplate, when PopupContent is null. I have corrected this issue for the next maintenance release. In the mean time, you can simply add this line:
popupButtonFactory.SetValue(PopupButton.PopupContentProperty, new object());
The ensures that the PopupContent is not null, so that the PopupContentTemplate is properly used.


Actipro Software Support

Posted 10 years ago by Balaram Barange
Avatar
Thanks. Its working.
The latest build of this product (v2018.1 build 0675) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.