Issue in ListView Item text Wrapping

guess_me_if_u_can 126 Reputation points
2020-03-13T19:02:34.253+00:00

I am creating a new control which has a Dependency Property named DisplayMemberPath . I'm binding that dependency property string value to ListView.DisplayMemberPath. But I have a requirement to wrap the Items in the ListView. I am unable to write an ItemTemplate for the listview hence i have only the property name as string and not the exact property or model object for binding. Help me to sort out the issue by providing the solution to wrap the listview item data with DisplayMemberPath and without ItemTemplate.

Universal Windows Platform (UWP)
{count} votes

Accepted answer
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-03-15T16:07:20.41+00:00

    Hi,
    try the following code

      public sealed partial class Page03UC1 : UserControl
      {
        public Page03UC1()
        {
          this.InitializeComponent();
        }
    
        public static readonly DependencyProperty DisplayMemberPathProperty =
          DependencyProperty.RegisterAttached("DisplayMemberPath", typeof(string),
            typeof(Page03UC1), new PropertyMetadata(string.Empty));
        public static string GetDisplayMemberPath(DependencyObject obj) => obj.GetValue(DisplayMemberPathProperty).ToString();
        public static void SetDisplayMemberPath(DependencyObject obj, String value) => obj.SetValue(DisplayMemberPathProperty, value);
      }
    
      public class AttProp
      {
        public static readonly DependencyProperty DataProperty =
        DependencyProperty.RegisterAttached("Data", typeof(Page03Data),
          typeof(AttProp), new PropertyMetadata(null, OnDataChanged));
        public static Page03Data GetData(DependencyObject obj) => obj.GetValue(DataProperty) as Page03Data;
        public static void SetData(DependencyObject obj, Page03Data value) => obj.SetValue(DataProperty, value);
    
        private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
          var tb = d as TextBlock;
          var data = e.NewValue as Page03Data;
          if (tb == null || data == null) return;
          var prop = data.GetType().GetProperty(tb.Tag.ToString());
          tb.Text = prop.GetValue(data).ToString();
        }
      }
    
    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Peter Fleischer (former MVP) 19,231 Reputation points
    2020-03-15T16:07:20.83+00:00

    Hi,
    you can use an attached property for binding the data object and the Tag property for binding the property name.

    XAML UserControl:

    <UserControl x:Name="uc"
        x:Class="App1.Page03UC1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
      <Grid>
        <Grid.Resources>
          <DataTemplate x:Name="dt">
            <Grid>
              <TextBlock local:AttProp.Data="{Binding}" 
                         Tag="{Binding ElementName=uc, Path=DisplayMemberPath}"
                         TextWrapping="WrapWholeWords"/>
            </Grid>
          </DataTemplate>
        </Grid.Resources>
        <ListView ItemsSource="{Binding View, Mode=OneWay}" 
                  ItemTemplate="{StaticResource dt}">
        </ListView>
      </Grid>
    </UserControl>
    

    And CodeBehind and attached property class:

    Public NotInheritable Class Page03UC1
      Inherits UserControl
    
      Public Shared ReadOnly DisplayMemberPathProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("DisplayMemberPath", GetType(String),
                                            GetType(Page03UC1), New PropertyMetadata(String.Empty))
    
      Public Shared Function GetDisplayMemberPath(obj As DependencyObject) As String
        Return CType(obj.GetValue(DisplayMemberPathProperty), String)
      End Function
    
      Public Shared Sub SetDisplayMemberPath(obj As DependencyObject, value As String)
        obj.SetValue(DisplayMemberPathProperty, value)
      End Sub
    
    End Class
    
    Public Class AttProp
    
      Public Shared ReadOnly DataProperty As DependencyProperty =
        DependencyProperty.RegisterAttached("Data", GetType(Page03Data), GetType(AttProp),
                                            New PropertyMetadata(Nothing, AddressOf OnDataChanged))
    
      Public Shared Function GetData(obj As DependencyObject) As Page03Data
        Return CType(obj.GetValue(DataProperty), Page03Data)
      End Function
    
      Public Shared Sub SetData(obj As DependencyObject, value As Page03Data)
        obj.SetValue(DataProperty, value)
      End Sub
    
      Private Shared Sub OnDataChanged(d As DependencyObject, e As DependencyPropertyChangedEventArgs)
        Dim tb = TryCast(d, TextBlock)
        Dim data = TryCast(e.NewValue, Page03Data)
        If tb Is Nothing OrElse data Is Nothing Then Exit Sub
        Dim prop = data.GetType.GetProperty(tb.Tag.ToString)
        tb.Text = prop.GetValue(data)
      End Sub
    
    End Class