0

I could not find the solution to this problem in internet. Can somebody please suggest me to correct this issue. Your help is much appreciated!

With reference to the following msdn forum: https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb882b44-dee0-41de-a10c-819de9a53f1a/force-a-usercontrols-width-to-stretch-to-parent-container-width?forum=wpf

I tried to set the UserControl width to ActualWidth of Listview in Mainwindow.

<UserControl ...
         Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, Path=ActualWidth}">

From the MainWindow, I added code to add Usercontrols to the ListView on a button click through the ViewModel command binding.

        UserControl1 uc1 = new UserControl1();
        ViewCollection.Add(uc1);

What I noticed is, if usercontrol is added in the display area of ListView, then the usercontrol is created with Width stretched to ListView's Width. Also this usercontrol is always resized to the ListView width when window is resized.

But if the usercontrol is added in the non-display area of ListView (when scrollbar is not scrolled where UserControl is added), then the usercontrol is created with its original defined width and the usercontrol does not resize to listview width. Also I can see a Binding error in OutputWindow (Debug):

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListView', AncestorLevel='1''. BindingExpression:Path=ActualWidth; DataItem=null; target element is 'UserControl1' (Name=''); target property is 'Width' (type 'Double')

<UserControl x:Class="BindingUCWidth.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d"
         Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ListView},
                Path=ActualWidth}">
    <Grid>
        <GroupBox Header="User Control 1">
            <StackPanel Orientation="Vertical">
                <Button Content="hello1" Width="Auto"/>
                <Button Content="hello2" Width="Auto"/>
            </StackPanel>
        </GroupBox>
    </Grid>
</UserControl>

<Window x:Class="BindingUCWidth.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:BindingUCWidth"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="30"/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1*"/>
        <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>
    <Button Grid.Row="0" Grid.Column="0" Content="Add UC 1" Command="{Binding AddUC1Command}"/>
    <Button Grid.Row="0" Grid.Column="1" Content="Add UC 2" Command="{Binding AddUC2Command}"/>
    <ListView x:Name="ViewsList" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" ItemsSource="{Binding ViewCollection}"
            BorderBrush="Black" BorderThickness="1,1,1,1" Margin="1"
            HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
            HorizontalContentAlignment="Stretch" VerticalContentAlignment="Bottom"
            ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible">
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <Setter Property="Focusable" Value="True"/>
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            </Style>
        </ListView.ItemContainerStyle>
    </ListView>
</Grid>

using System;
using System.Windows.Input;

namespace BindingUCWidth
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        MainViewModel mvm = new MainViewModel();
        this.DataContext = mvm;
    }
}

public class MainViewModel
{
    public ObservableCollection<UserControl> ViewCollection { get; set; }
    public ICommand AddUC1Command { get; set; }
    public ICommand AddUC2Command { get; set; }

    public MainViewModel()
    {
        ViewCollection = new ObservableCollection<UserControl>();
        AddUC1Command = new RelayCommand(param => AddUC1RelayCommand());
        AddUC2Command = new RelayCommand(param => AddUC2RelayCommand());
    }

    private void AddUC1RelayCommand()
    {
        UserControl1 uc1 = new UserControl1();
        ViewCollection.Add(uc1);
    }

    private void AddUC2RelayCommand()
    {
        UserControl2 uc2 = new UserControl2();
        ViewCollection.Add(uc2);
    }
}

public class RelayCommand : ICommand

{
    private Action<object> execute;
    private Func<object, bool> canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {
        return this.canExecute == null || this.canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        this.execute(parameter);
    }
}
}

Image files attached.

UserControl resized properly - case 1 UserControl not resized, Binding error - case 2

1 Answers1

0

The answer was given by MSFT expert. https://social.msdn.microsoft.com/Forums/vstudio/en-US/53ed166e-2236-47b9-a628-350ea3ce122b/wpf-relativesource-actualwidth-binding-error-when-added-usercontrol-is-not-in-display-area-of?forum=wpf

"It is caused by the WPF ListView virtualization.

You can disable the ListView virtualization to solve this issue.

Set VirtualizingStackPanel.IsVirtualizing to false on the ListView or set a normal StackPanel as the ListView.ItemsPanel.

 VirtualizingStackPanel.IsVirtualizing="False"

Or:

<ListView.ItemsPanel>
     <ItemsPanelTemplate>
       <StackPanel></StackPanel>
      </ItemsPanelTemplate>
  </ListView.ItemsPanel>

"