Почему мой текст TreeViewItem не переносится в моем примере кода? Как заставить это обернуть? - PullRequest
0 голосов
/ 08 мая 2018

Почему мой TreeViewItem не переносится в моем примере кода?

enter image description here

Xaml:

<Window x:Class="WpfAppTestScrollViewBehavior.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfAppTestScrollViewBehavior"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainWindowModel></local:MainWindowModel>
    </Window.DataContext>

    <TabControl>
        <TabItem Header="Test">
            <TreeView ItemsSource="{Binding Level1s, Mode=OneWay}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                      Background="LightGoldenrodYellow">
                <TreeView.Resources>
                    <HierarchicalDataTemplate DataType="{x:Type local:Level1}"
                                            ItemsSource="{Binding Path=InstalledFontCollection}">
                        <Grid HorizontalAlignment="Stretch" Background="LightGreen">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"></ColumnDefinition>
                                <ColumnDefinition></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <CheckBox Grid.Column="0" IsChecked="{Binding Path=IsSelected}"></CheckBox>
                            <TextBlock Grid.Column="1" Text="{Binding Path=Name}" 
                                        TextWrapping="Wrap" Margin="5,0,0,0"></TextBlock>
                        </Grid>
                    </HierarchicalDataTemplate>
                </TreeView.Resources>
            </TreeView>
        </TabItem>
    </TabControl>
</Window>

Код:

using System;
using System.Collections.Generic;

namespace WpfAppTestScrollViewBehavior
{
    public class MainWindowModel
    {
        public List<Level1> Level1s { get; } = new List<Level1>();

        public MainWindowModel()
        {
            Level1s.Add(new Level1());
        }
    }
}


using System;
using System.Drawing.Text;

namespace WpfAppTestScrollViewBehavior
{
    public class Level1
    {
        public bool IsSelected { get; set; }
        public string Name { get; set; } = "a very long name in order to test text wrapping functionnality";

        public InstalledFontCollection InstalledFontCollection { get; } = new InstalledFontCollection();
    }
}

Только для предотвращения быстрых неправильных ответов:

Вы можете добавить этот код, и он отлично работает:

<TabItem Header="Test 2">
    <ScrollViewer HorizontalScrollBarVisibility="Disabled">
        <Grid HorizontalAlignment="Stretch" Background="LightPink">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <CheckBox Grid.Column="0"></CheckBox>
            <TextBlock Grid.Column="1" Text="long name just for testing" 
                        TextWrapping="Wrap" Margin="5,0,0,0"></TextBlock>
        </Grid>
    </ScrollViewer>
</TabItem>

Результаты предыдущего рабочего кода (как пример того, что я ожидаю):

enter image description here

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Поскольку вы не указали Width, это дает Width на <Textblock>

Почему мой TreeViewItem не переносится в моем примере кода?

Текст переносится, но из-за неограниченной ширины доступного переноса не видно

Например:

XAML: ширина: 150 единиц TextWrapping = "NoWrap"

<TextBlock Grid.Column="1" Text="{Binding Path=Name}"   Width="150" Name="textblock1"
                                        TextWrapping="NoWrap" Margin="10,0,0,0"></TextBlock>

ВЫВОД: enter image description here

XAML: ширина: 150 единиц TextWrapping = "Wrap"

<TextBlock Grid.Column="1" Text="{Binding Path=Name}"   Width="150" Name="textblock1"
                                        TextWrapping="Wrap" Margin="10,0,0,0"></TextBlock>

OR

<Grid HorizontalAlignment="Stretch" Width="150" Background="LightGreen">
     public string Name { get; set; } = ;

enter image description here

0 голосов
/ 10 мая 2018

Я придумал решение, которое является общим и, кажется, работает для любых случаев, независимо от содержимого внутри TreeViewItem.Это может быть применено как поведение (я предпочитаю это для упрощения использования).

Одно ограничение использования этого поведения: Определите поведение как последний элемент в xaml TreeView.Таким образом он будет поддерживать любой дополнительный ранее определенный ItemContainerStyle.

Код поведения:

using System;
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using HQ.Wpf.Util;
using HQ.Wpf.Util.Converter;

namespace WpfAppTestScrollViewBehavior
{
    public class BehaviorTreeView : Behavior<TreeView>
    {
        public static readonly DependencyProperty ShowHorizontalScrollBarProperty = DependencyProperty.Register(
            "PropertyType", typeof(bool), typeof(BehaviorTreeView), new PropertyMetadata(true));

        /// <summary>
        /// Settting this poroperty to false will fake a TreeView-ScrollView ViewPort finite width. 
        /// TreeViewItem will be advise to Calculate their width according to the width of the 
        /// ViewPort of the ScrollView of the TreeView.
        /// </summary>
        public bool ShowHorizontalScrollBar
        {
            get { return (bool)GetValue(ShowHorizontalScrollBarProperty); }
            set { SetValue(ShowHorizontalScrollBarProperty, value); }
        }

        // ******************************************************************   
        protected override void OnAttached()
        {
            base.OnAttached();

            if (!ShowHorizontalScrollBar)
            {
                Style style = AssociatedObject.ItemContainerStyle ?? new Style(typeof(TreeViewItem));
                var eventSetter = new EventSetter(FrameworkElement.LoadedEvent, new RoutedEventHandler(this.TreeViewItemLoaded));
                style.Setters.Add(eventSetter);
                AssociatedObject.ItemContainerStyle = style;
            }
        }

        // ******************************************************************   
        private void TreeViewItemLoaded(object sender, RoutedEventArgs e)
        {
            var tvi = sender as TreeViewItem;
            var contentPresenter = tvi.FindFirstChildWithNameRecursive<ContentPresenter>("PART_Header");

            var treeView = tvi.GetVisualParentRecursive<TreeView>();

            double offsetX = contentPresenter.TransformToAncestor(treeView).Transform(new Point(0, 0)).X;

            var scrollViewer = treeView.FindVisualChild<ScrollViewer>();

            Binding binding = new Binding();
            binding.Source = scrollViewer;
            binding.Path = new PropertyPath(nameof(ScrollViewer.ViewportWidth));
            binding.Mode = BindingMode.OneWay;

            var converter = new NumericFixedNumberAddedConverter();
            binding.Converter = converter;
            binding.ConverterParameter = -offsetX;

            BindingOperations.SetBinding(contentPresenter, FrameworkElement.WidthProperty, binding);
        }

        // ******************************************************************   

    }
}

Зависимости поведения:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;

namespace WpfAppTestScrollViewBehavior
{
    class NumericFixedNumberAddedConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            try
            {
                return (double) value + double.Parse(parameter.ToString());
            }
            catch (Exception ex)
            {
                Debug.Print(ex.ToString());
                return value;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace WpfAppTestScrollViewBehavior
{
    public static class UiUtility
    {
        // ******************************************************************
        public static Window GetTopLevelOwnerWindowOrMainAppWindow(Control usercontrol)
        {
            return GetTopLevelOwnerWindow(usercontrol) ?? Application.Current.MainWindow;
        }

        // ******************************************************************
        public static Window GetTopLevelOwnerWindowOrMainAppWindow(DependencyObject dependencyObject)
        {
            return GetTopLevelOwnerWindow(dependencyObject) ?? Application.Current.MainWindow;
        }

        // ******************************************************************
        public static Window GetTopLevelOwnerWindow(Control usercontrol)
        {
            return GetTopLevelOwnerWindow((DependencyObject)usercontrol);
        }

        // ******************************************************************
        public static Window GetTopLevelOwnerWindow(DependencyObject dependencyObject)
        {
            while (dependencyObject != null && !(dependencyObject is Window))
            {
                var dependencyObjectCopy = dependencyObject;
                dependencyObject = VisualTreeHelper.GetParent(dependencyObject);

                if (dependencyObject == null)
                {
                    dependencyObject = dependencyObjectCopy;
                    String propName = "DockSite";
                    PropertyInfo pi = dependencyObject.GetType().GetProperty(propName);
                    if (pi != null)
                    {
                        DependencyObject dependencyObjectTemp = null;
                        try
                        {
                            dependencyObjectTemp = dependencyObject.GetType().InvokeMember(propName,
                                BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public, null, dependencyObject, null) as DependencyObject;
                        }
                        catch (Exception)
                        {

                        }

                        if (dependencyObjectTemp != null)
                        {
                            dependencyObject = LogicalTreeHelper.GetParent(dependencyObjectTemp);
                        }
                        else
                        {
                            dependencyObject = LogicalTreeHelper.GetParent(dependencyObject);
                        }
                    }
                    else
                    {
                        dependencyObject = LogicalTreeHelper.GetParent(dependencyObject);
                    }
                }
            }

            return dependencyObject as Window;
        }

        // ******************************************************************
        public static T FindVisualParent<T>(DependencyObject element) where T : DependencyObject
        {
            var parent = element;
            while (parent != null)
            {
                var correctlyTyped = parent as T;
                if (correctlyTyped != null)
                {
                    return correctlyTyped;
                }

                parent = VisualTreeHelper.GetParent(parent) as DependencyObject;

            }
            return null;
        }

        // ******************************************************************
        public static bool IsParentOf(DependencyObject parent, DependencyObject child)
        {
            if (parent == null || child == null)
            {
                return false;
            }

            DependencyObject childParent = child;
            do
            {
                if (childParent == parent)
                {
                    return true;
                }

                childParent = VisualTreeHelper.GetParent(childParent);
            } while (childParent != null);

            return false;
        }

        // ******************************************************************
        public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
        {
            if (depObj != null)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                    if (child != null && child is T)
                    {
                        yield return (T)child;
                    }

                    foreach (T childOfChild in FindVisualChildren<T>(child))
                    {
                        yield return childOfChild;
                    }
                }
            }
        }

        // ******************************************************************
        public static DataGridColumnHeader GetColumnHeaderFromColumn(DataGrid dataGrid, DataGridColumn column)
        {
            // dataGrid is the name of your DataGrid. In this case Name="dataGrid"
            foreach (var columnHeader in FindVisualChildren<DataGridColumnHeader>(dataGrid))
            {
                if (columnHeader.Column == column)
                {
                    return columnHeader;
                }
            }
            return null;
        }

        // ******************************************************************
        public static void SafeInvoke(Action action)
        {
            if (Application.Current.Dispatcher.CheckAccess())
            {
                action();
            }
            else
            {
                Application.Current.Dispatcher.Invoke(action);
            }
        }

        // ******************************************************************
        public static void SafeBeginInvoke(Action action)
        {
            if (Application.Current.Dispatcher.CheckAccess())
            {
                action();
            }
            else
            {
                Application.Current.Dispatcher.BeginInvoke(action);
            }
        }

        // ******************************************************************
        public static void BindingRefresh(DependencyObject dependencyObject, DependencyProperty dependencyProperty)
        {
            BindingExpressionBase b = BindingOperations.GetBindingExpressionBase(dependencyObject, dependencyProperty);
            if (b != null)
            {
                b.UpdateTarget();
            }
        }

        // ******************************************************************
        /// <summary>
        /// Finds a Child of a given item in the visual tree. 
        /// </summary>
        /// <param name="parent">A direct parent of the queried item.</param>
        /// <typeparam name="T">The type of the queried item.</typeparam>
        /// <param name="childName">x:Name or Name of child. </param>
        /// <returns>The first parent item that matches the submitted type parameter. 
        /// If not matching item can be found, 
        /// a null parent is being returned.</returns>
        public static T FindChild<T>(DependencyObject depObj, string childName)
            where T : DependencyObject
        {
            // Confirm obj is valid. 
            if (depObj == null) return null;

            // success case
            if (depObj is T && ((FrameworkElement)depObj).Name == childName)
                return depObj as T;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);

                //DFS
                T obj = FindChild<T>(child, childName);

                if (obj != null)
                    return obj;
            }

            return null;
        }

        // ******************************************************************
        public static void DebugPrintControlParentHierarchy(object frameworkElement)
        {
            StringBuilder hierarchy = new StringBuilder();
            var fe = frameworkElement as FrameworkElement;
            while (fe != null)
            {
                hierarchy.Append(String.Format("{0} [{1}] ==> ", fe.GetType(), fe.Name));
                fe = VisualTreeHelper.GetParent(fe) as FrameworkElement;
            }

            hierarchy.Append("!TOP!");

            Debug.Print(hierarchy.ToString());
        }

        // ******************************************************************
        /// <summary>
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static T FindVisualChild<T>(this DependencyObject obj) where T : DependencyObject
        {
            if (obj != null && obj is Visual)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    var visualChild = child as T;
                    if (visualChild != null)
                        return visualChild;
                    else
                    {
                        T childOfChild = FindVisualChild<T>(child);
                        if (childOfChild != null)
                            return childOfChild;
                    }
                }
            }
            return null;
        }

        // ******************************************************************
        public static FrameworkElement GetVisualParent(this UIElement element)
        {
            DependencyObject parent = VisualTreeHelper.GetParent(element);
            do
            {
                var fe = parent as FrameworkElement;
                if (fe != null)
                {
                    return fe;
                }
                parent = VisualTreeHelper.GetParent(parent);
            } while (parent != null);

            return null;
        }

        // ******************************************************************
        public static void BringToFront(this Panel panel, UIElement element)
        {
            int maxIndex = 0;
            foreach (UIElement e in panel.Children)
            {
                maxIndex = Math.Max(maxIndex, Panel.GetZIndex(e));
            }

            Panel.SetZIndex(element, maxIndex + 1);
        }

        //// ******************************************************************
        ///// <summary>
        ///// Return the center point of an direct child of a Canvas (not yet tested)
        ///// </summary>
        ///// <param name=""></param>
        ///// <param name="elementRelativeTo">If elementRelativeTo == null, will use direct parent</param>
        ///// <returns></returns>
        //public static Point GetCanvasElementCenterPoint(this FrameworkElement element)
        //{
        //  return new Point(
        //      Canvas.GetLeft(element) + (element.ActualWidth / 2),
        //      Canvas.GetTop(element) + (element.ActualHeight / 2));
        //}

        // ******************************************************************
        public enum PointPositionVertical
        {
            Top,
            Center,
            Bottom
        }

        // ******************************************************************
        public enum PointPositionHorizontal
        {
            Left,
            Center,
            Right
        }

        // ******************************************************************
        public static Point GetChildCoordinate(this UIElement elementContainer, FrameworkElement childElement,
            PointPositionHorizontal pointPositionHorizontal = PointPositionHorizontal.Left,
            PointPositionVertical pointPositionVertical = PointPositionVertical.Top)
        {
            double x;
            switch (pointPositionHorizontal)
            {
                case PointPositionHorizontal.Center:
                    x = childElement.ActualWidth / 2;
                    break;
                case PointPositionHorizontal.Right:
                    x = childElement.ActualWidth;
                    break;
                default:
                    x = 0;
                    break;
            }

            double y;
            switch (pointPositionVertical)
            {
                case PointPositionVertical.Center:
                    y = childElement.ActualHeight / 2;
                    break;
                case PointPositionVertical.Bottom:
                    y = childElement.ActualHeight;
                    break;
                default:
                    y = 0;
                    break;
            }

            return childElement.TranslatePoint(new Point(x, y), elementContainer);
        }

        // ******************************************************************
        public static void ApplyToEachVisualChildRecursively(this DependencyObject obj, Action<DependencyObject> action)
        {
            if (obj != null && obj is Visual)
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    if (child != null)
                    {
                        action(child);
                        ApplyToEachVisualChildRecursively(child, action);
                    }
                }
            }
        }

        // ******************************************************************
        public static T GetVisualParentRecursive<T>(this DependencyObject obj) where T : class
        {
            var element = obj as FrameworkElement;
            if (element != null)
            {
                var frameWorkElement = VisualTreeHelper.GetParent(element) as FrameworkElement;
                if (frameWorkElement != null)
                {
                    var t = frameWorkElement as T;
                    if (t != null)
                    {
                        return t;
                    }
                    return frameWorkElement.GetVisualParentRecursive<T>();
                }
            }

            return null;
        }

        // ******************************************************************
        public static T HitTest<T>(this Visual visual, Point pt) where T : class
        {
            T hitResult = null;

            VisualTreeHelper.HitTest(visual, null, result =>
            {
                if (result.VisualHit is T)
                {
                    hitResult = result.VisualHit as T;
                    return HitTestResultBehavior.Stop;
                }

                hitResult = result.VisualHit?.GetVisualParentRecursive<T>();
                if (hitResult != null)
                {
                    return HitTestResultBehavior.Stop;
                }

                return HitTestResultBehavior.Continue;

            }, new PointHitTestParameters(pt));

            return hitResult;
        }

        // ******************************************************************
        public static IEnumerable<T> GetChildrenRecursive<T>(this DependencyObject depObj) where T : class
        {
            int count = VisualTreeHelper.GetChildrenCount(depObj);
            for (int n = 0; n < count; n++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, n);
                if (child is T)
                {
                    yield return child as T;
                }

                foreach (T depObjChild in child.GetChildrenRecursive<T>())
                {
                    yield return depObjChild;
                }
            }
        }

        // ******************************************************************
        /// <summary>
        /// EO, 2017-05-11: New code
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static T GetVisualParentRecursive<T>(this DependencyObject obj, Predicate<T> predicate = null) where T : class
        {
            var element = obj as FrameworkElement;
            if (element != null)
            {
                var frameWorkElement = VisualTreeHelper.GetParent(element) as FrameworkElement;
                if (frameWorkElement != null)
                {
                    var t = frameWorkElement as T;
                    if (t != null)
                    {
                        if (predicate == null || predicate(t))
                        {
                            return t;
                        }
                    }
                    return frameWorkElement.GetVisualParentRecursive<T>(predicate);
                }
            }

            return null;
        }

        // ******************************************************************   
        /// <summary>
        /// EO, 2017-05-11: New code
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static T FindFirstChildWithNameRecursive<T>(this DependencyObject parent, string name) where T : FrameworkElement
        {
            return FindFirstChildRecursive(parent, (T child) => child.Name == name);
        }

        // ******************************************************************   
        /// <summary>
        /// Find all controls (visual or not)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static T FindFirstChildRecursive<T>(this DependencyObject parent, Predicate<T> predicate = null) where T : DependencyObject
        {
            if (parent == null)
            {
                return null;
            }

            //use the visual tree for Visual / Visual3D elements
            if (parent is Visual || parent is Visual3D)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
                for (int i = 0; i < count; i++)
                {
                    var child = VisualTreeHelper.GetChild(parent, i);
                    var childAsT = child as T;
                    if (childAsT != null)
                    {
                        if (predicate == null || predicate(childAsT))
                        {
                            return childAsT;
                        }
                    }

                    var result = FindFirstChildRecursive(child, predicate);
                    if (result != null)
                    {
                        return result;
                    }
                }
            }
            else //use the logical tree for content / framework elements
            {
                foreach (DependencyObject child in LogicalTreeHelper.GetChildren(parent))
                {
                    var childAsT = child as T;
                    if (childAsT != null)
                    {
                        if (predicate == null || predicate(childAsT))
                        {
                            return childAsT;
                        }
                    }

                    var result = FindFirstChildRecursive(child, predicate);
                    if (result != null)
                    {
                        return result;
                    }
                }
            }

            return null;
        }

        // ******************************************************************   
        /// <summary>
        /// Non recursive
        /// Based on stackoverflow: http://stackoverflow.com/questions/13248013/visualtreehelper-not-finding-children-of-dependencyobject-how-can-i-reliably-fi
        /// Find all controls (visual or not)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static IEnumerable<T> FindChilds<T>(this DependencyObject parent, Predicate<T> predicate) where T : DependencyObject
        {
            if (parent == null) yield break;

            //use the visual tree for Visual / Visual3D elements
            if (parent is Visual || parent is Visual3D)
            {
                int count = VisualTreeHelper.GetChildrenCount(parent);
                for (int i = 0; i < count; i++)
                {
                    var childAsT = VisualTreeHelper.GetChild(parent, i) as T;
                    if (childAsT != null)
                    {
                        if (predicate(childAsT))
                        {
                            yield return childAsT;
                        }
                    }
                }
            }
            else //use the logical tree for content / framework elements
            {
                foreach (DependencyObject obj in LogicalTreeHelper.GetChildren(parent))
                {
                    var childAsT = obj as T;
                    if (childAsT != null)
                    {
                        if (predicate(childAsT))
                        {
                            yield return childAsT;
                        }
                    }
                }
            }
        }

        // ******************************************************************   
        /// <summary>
        /// EO, 2017-05-11: New code
        /// Find all controls (visual or not)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static List<T> FindChildsWithNameRecursive<T>(this DependencyObject parent, string name) where T : FrameworkElement
        {
            return FindChildsRecursive(parent, (T child) => child.Name == name);
        }

        // ******************************************************************   
        /// <summary>
        /// Find all controls (visual or not)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="parent"></param>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public static List<T> FindChildsRecursive<T>(this DependencyObject parent, Predicate<T> predicate = null) where T : DependencyObject
        {
            List<T> childs = new List<T>();
            return FindChildsRecursiveInternal(parent, predicate, childs);
        }

        // ******************************************************************   
        private static List<T> FindChildsRecursiveInternal<T>(this DependencyObject parent, Predicate<T> predicate, List<T> childs) where T : DependencyObject
        {
            if (parent != null)
            {
                //use the visual tree for Visual / Visual3D elements
                if (parent is Visual || parent is Visual3D)
                {
                    int count = VisualTreeHelper.GetChildrenCount(parent);
                    for (int i = 0; i < count; i++)
                    {
                        var child = VisualTreeHelper.GetChild(parent, i);
                        var childAsT = child as T;
                        if (childAsT != null)
                        {
                            if (predicate == null || predicate(childAsT))
                            {
                                childs.Add(childAsT);
                            }
                        }

                        FindChildsRecursiveInternal(child, predicate, childs);
                    }
                }
                else //use the logical tree for content / framework elements
                {
                    foreach (DependencyObject child in LogicalTreeHelper.GetChildren(parent))
                    {
                        var childAsT = child as T;
                        if (childAsT != null)
                        {
                            if (predicate == null || predicate(childAsT))
                            {
                                childs.Add(childAsT);
                            }
                        }

                        FindChildsRecursiveInternal(child, predicate, childs);
                    }
                }
            }

            return childs;
        }

        // ******************************************************************   }
    }
}

Использование:

        <!-- ScrollViewer.HorizontalScrollBarVisibility="Disabled" -->
        <TreeView ItemsSource="{Binding Level1s, Mode=OneWay}">

            ...

            <i:Interaction.Behaviors>
                <local:BehaviorTreeView ShowHorizontalScrollBar="False"></local:BehaviorTreeView>
            </i:Interaction.Behaviors>

Спасибо Дину Куге.Его решение дает мне начало тому, что я придумал.

Результаты:

enter image description here

0 голосов
/ 08 мая 2018

ColumnDefinition по умолчанию *, поэтому TextBlock в столбце 1 займет все доступное пространство.

Попробуйте поэкспериментировать с MaxWidth вот так: <ColumnDefinition Width="Auto" MaxWidth="100"/>

EDIT

Если вы не хотите использовать предопределенные Width или MaxWidth, привяжите Width из Grid к ActualWidth из TabControl следующим образом:

<Grid Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabControl}}, Path=ActualWidth}" />

Я только что проверил этот подход, и он обернул TextBlock штрафа и повторно обернул его, когда я изменил размер окна ... Если текст TextBlock не имеет поля относительно правой границы окна, когда установлена ​​ширина таким образом, вы можете исправить это, установив правое поле TextBlock равным 10 или более в зависимости от требуемого отступа ...

...