0

我在互联网上找不到这个问题的解决方案。有人可以建议我纠正这个问题。非常感谢您的帮助!

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

我试图在主窗口中将 UserControl 宽度设置为 Listview 的 ActualWidth。

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

在 MainWindow 中,我添加了代码以通过 ViewModel 命令绑定单击按钮将 Usercontrols 添加到 ListView。

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

我注意到的是,如果在 ListView 的显示区域中添加了 usercontrol,那么创建的 usercontrol 的宽度会拉伸到 ListView 的宽度。此外,在调整窗口大小时,此用户控件的大小始终调整为 ListView 宽度。

但是如果在 ListView 的非显示区域中添加了 usercontrol(当添加了 UserControl 的地方没有滚动滚动条时),那么 usercontrol 会以其原始定义的宽度创建,并且 usercontrol 不会调整为 listview 宽度。我还可以在 OutputWindow (Debug) 中看到绑定错误:

System.Windows.Data 错误:4:找不到与引用“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.ListView',AncestorLevel='1''的绑定源。绑定表达式:路径=实际宽度;数据项=空;目标元素是'UserControl1'(名称='');目标属性是“宽度”(类型“双”)

<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);
    }
}
}

附加图像文件。

UserControl 已正确调整大小 - 案例 1 UserControl 未调整大小,绑定错误 - 案例 2

4

1 回答 1

0

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

“这是由 WPF ListView 虚拟化引起的。

您可以禁用 ListView 虚拟化来解决此问题。

在 ListView 上将 VirtualizingStackPanel.IsVirtualizing 设置为 false 或将普通 StackPanel 设置为 ListView.ItemsPanel。

 VirtualizingStackPanel.IsVirtualizing="False"

或者:

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

"

于 2019-07-23T06:23:30.100 回答