简体   繁体   English

wpf-当添加的用户控件不在ListView的显示区域中时,RelativeSource ActualWidth绑定错误

[英]wpf - RelativeSource ActualWidth binding error when added usercontrol is not in display area of ListView

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 参考以下msdn论坛: https : //social.msdn.microsoft.com/Forums/vstudio/en-US/fb882b44-dee0-41de-a10c-819de9a53f1a/force-a-usercontrols-width-to-stretch-到父容器宽度?论坛= wpf

I tried to set the UserControl width to ActualWidth of Listview in Mainwindow. 我试图在Mainwindow中将UserControl宽度设置为Listview的ActualWidth。

<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. 在MainWindow中,我添加了代码,以通过单击ViewModel命令绑定将按钮上的Usercontrols添加到ListView。

        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. 我注意到的是,如果将usercontrol添加到ListView的显示区域中,则将使用Width扩展到ListView的Width创建usercontrol。 Also this usercontrol is always resized to the ListView width when window is resized. 同样,在调整窗口大小时,此用户控件也始终调整为ListView宽度。

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. 但是,如果将用户控件添加到ListView的非显示区域中(当滚动条未滚动到添加了UserControl的位置时),则将使用其原始定义的宽度创建该用户控件,并且该用户控件的大小不会调整为ListView宽度。 Also I can see a Binding error in OutputWindow (Debug): 我也可以在OutputWindow(Debug)中看到Binding错误:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListView', AncestorLevel='1''. System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ListView',AncestorLevel ='1''的绑定源。 BindingExpression:Path=ActualWidth; BindingExpression:Path = ActualWidth; DataItem=null; DataItem = null; target element is 'UserControl1' (Name=''); 目标元素是'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 UserControl的大小正确调整-情况1 UserControl的大小未调整,绑定错误-情况2

The answer was given by MSFT expert. 答案是由MSFT专家给出的。 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 https://social.msdn.microsoft.com/Forums/vstudio/zh-CN/53ed166e-2236-47b9-a628-350ea3ce122b/wpf-relativesource-actualwidth-binding-error-when-add-usercontrol-is-not-在显示区域中的论坛= wpf

"It is caused by the WPF ListView virtualization. “这是由WPF ListView虚拟化引起的。

You can disable the ListView virtualization to solve this issue. 您可以禁用ListView虚拟化来解决此问题。

Set VirtualizingStackPanel.IsVirtualizing to false on the ListView or set a normal StackPanel as the ListView.ItemsPanel. 在ListView上将VirtualizingStackPanel.IsVirtualizing设置为false,或将常规StackPanel设置为ListView.ItemsPanel。

 VirtualizingStackPanel.IsVirtualizing="False"

Or: 要么:

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

"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM