2

私は数年前にビルドされた WPF プロジェクトに取り組んでいます。

1 つのコントロールは、チェック コントロールのリストをグループ化する展開コントロールです。

このチェック コントロールのリストは、WrapPanel によって左から右、上から下に配置されます。

ここでの目標は、チェック コントロールを上から下、左から右に配置して、親ウィンドウの下部で垂直方向の折り返しが発生するようにすることです。これを達成するためのヒント/指示は素晴らしいでしょう!!

問題を強調するために、コード例で問題を抽出しました。

例の動作: コード例では、WrapPanel の方向が水平に設定されています。これは、私が達成したい行動の種類を示すためのものです! 親ウィンドウの右側で折り返しが切れ、新しい行が開始されます。チェック コントロールが画面の下部からはみ出すと、垂直スクロールバーが表示されます。

私が達成したい動作: 親ウィンドウの下側に到達したとき (wrappanel が垂直方向に設定されているとき)、ラップを中断して再び上から開始したい。チェック コントロールがウィンドウの右側からはみ出すと、水平スクロールバーが表示されます。

例: コード: Wrappanel の Orientation 属性を Vertical に変更します。オーバーフローしている列が 1 つだけあり、ウィンドウの下部にラップがないことに注意してください。(デモ プロジェクトで) zip ファイルを添付する方法がわからないため、以下のコード ファイルを追加しました。WPF アプリケーション (.net Framework 3.5) を作成し、コードを適切な場所にコピーするだけで十分です。サンプルの実行に問題がある場合は、いつでも VS2010 ソリューションを郵送できます。

VerticalWrapPanel というプロジェクト

ユーザー コントロール CheckControl.xaml

<UserControl x:Class="VerticalWrapPanel.CheckControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Border BorderThickness="1,1,1,1" BorderBrush="Black">
        <Label Content="{Binding Label}"/>
    </Border>
</UserControl>

ユーザー コントロール CheckGroupControl.xaml

<UserControl x:Class="VerticalWrapPanel.CheckGroupControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controls="clr-namespace:VerticalWrapPanel"
             x:Name="GroupControl">

<UserControl.Resources>
    <DataTemplate x:Key="CheckTemplate">
        <controls:CheckControl />
    </DataTemplate>
</UserControl.Resources>

<Expander BorderBrush="Black" Header="TEST" IsExpanded="{Binding ElementName=GroupControl, Path=IsExpanded}">
    <ItemsControl ItemsSource="{Binding Checks}" ItemTemplate="{StaticResource CheckTemplate}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Expander>
</UserControl>

CheckGroupControl.xaml.cs

using System.Windows;
using System.Windows.Controls;

namespace VerticalWrapPanel
{
    /// <summary>
    /// Interaction logic for CheckGroupControl.xaml
    /// </summary>
    public partial class CheckGroupControl : UserControl
    {
        public CheckGroupControl()
        {
            InitializeComponent();
        }

        public static DependencyProperty IsExpandedProperty = DependencyProperty.Register("IsExpanded", typeof(bool), typeof(CheckGroupControl));
        public bool IsExpanded
        {
            get { return (bool)GetValue(IsExpandedProperty); }
            set { SetValue(IsExpandedProperty, value); }
        }

    }
}

MainWindow.xaml

<Window x:Class="VerticalWrapPanel.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:controls="clr-namespace:VerticalWrapPanel"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">

    <Window.Resources>
        <DataTemplate x:Key="CheckGroupsTemplate">
            <controls:CheckGroupControl />
        </DataTemplate>
    </Window.Resources>

    <ScrollViewer CanContentScroll="False">
        <ItemsControl ItemsSource="{Binding CheckGroups}" ItemTemplate="{StaticResource CheckGroupsTemplate}" />
    </ScrollViewer>
</Window>

MainWindow.xaml.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;

namespace VerticalWrapPanel
{
    public class MyModel
    {
        public ObservableCollection<CheckGroup> CheckGroups { get; set; }
    }

    public class Check
    {
        public string Label { get; set; }
    }

    public class CheckGroup
    {
        public List<Check> Checks { get; set; }
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            DataContext = new MyModel
                                   {
                                       CheckGroups = new ObservableCollection<CheckGroup>
                                                         {
                                                             new CheckGroup
                                                                 {
                                                                     Checks =
                                                                         new List<Check>
                                                                             {
                                                                                  new Check {Label = "Check 0001"}
                                                                                 ,new Check {Label = "Check 0002"}
                                                                                 ,new Check {Label = "Check 0003"}
                                                                                 ,new Check {Label = "Check 0004"}
                                                                                 ,new Check {Label = "Check 0005"}
                                                                                 ,new Check {Label = "Check 0006"}
                                                                                 ,new Check {Label = "Check 0007"}
                                                                                 ,new Check {Label = "Check 0008"}
                                                                                 ,new Check {Label = "Check 0009"}
                                                                                 ,new Check {Label = "Check 0000"}
                                                                                 ,new Check {Label = "Check 0002"}
                                                                                 ,new Check {Label = "Check 0003"}
                                                                                 ,new Check {Label = "Check 0004"}
                                                                                 ,new Check {Label = "Check 0005"}
                                                                                 ,new Check {Label = "Check 0006"}
                                                                                 ,new Check {Label = "Check 0007"}
                                                                                 ,new Check {Label = "Check 0008"}
                                                                                 ,new Check {Label = "Check 0009"}
                                                                                 ,new Check {Label = "Check 0000"}
                                                                                 ,new Check {Label = "Check 0002"}
                                                                                 ,new Check {Label = "Check 0003"}
                                                                                 ,new Check {Label = "Check 0004"}
                                                                                 ,new Check {Label = "Check 0005"}
                                                                                 ,new Check {Label = "Check 0006"}
                                                                                 ,new Check {Label = "Check 0007"}
                                                                                 ,new Check {Label = "Check 0008"}
                                                                                 ,new Check {Label = "Check 0009"}
                                                                                 ,new Check {Label = "Check 0000"}
                                                                             }
                                                                 }
                                                              , new CheckGroup
                                                                 {
                                                                     Checks =
                                                                         new List<Check>
                                                                             {
                                                                                  new Check {Label = "Check 0011"}
                                                                                 ,new Check {Label = "Check 0012"}
                                                                                 ,new Check {Label = "Check 0013"}
                                                                                 ,new Check {Label = "Check 0014"}
                                                                                 ,new Check {Label = "Check 0015"}
                                                                                 ,new Check {Label = "Check 0016"}
                                                                                 ,new Check {Label = "Check 0017"}
                                                                                 ,new Check {Label = "Check 0018"}
                                                                                 ,new Check {Label = "Check 0019"}
                                                                                 ,new Check {Label = "Check 0010"}
                                                                             }
                                                                 }
                                                         }

                                   };
        }
    }
}
4

3 に答える 3

2

アイテムコントロールでVerticalScrollBarVisibility="Disabled"とを設定してみてください。HorizontalScrollBarVisibility="Auto"これにより、垂直スクロールが無効になります。また、アイテムコントロールのテンプレートを変更して、スクロールを有効にするための優れたスクロールビューアを含めます。

<Expander BorderBrush="Black" Header="TEST" IsExpanded="{Binding ElementName=GroupControl,     Path=IsExpanded}">
    <ItemsControl ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemsSource="{Binding Checks}" ItemTemplate="{StaticResource CheckTemplate}">
        <ItemsControl.Template>
            <ControlTemplate>
                <ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
                    <ItemsPresenter />
                </ScrollViewer>
            </ControlTemplate>
        </ItemsControl.Template>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical" IsItemsHost="True" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Expander>

アップデート

あなたのコードはまだ1列のアイテムで進んでいます-それはあなたの場合は正常です。私が投稿したXAMLコードは、最上位のアイテムの高さを制限した場合にのみ機能します(たとえば、Heightまたはを使用MaxHeight)。私のXAMLコードは、エクスパンダー用のスペースが限られていることを前提としており、ItemsControl内にそのエクスパンダーを表示して、アイテムに必要なだけのスペースを提供しています。たとえば、データテンプレートを次のように変更します。

<Window.Resources>
    <DataTemplate x:Key="CheckGroupsTemplate">
        <controls:CheckGroupControl MaxHeight="100"/>
    </DataTemplate>
</Window.Resources>

これで、エキスパンダーの高さが最大になり、それに達するとラッピングが開始されます。それがないとMaxHeight、エキスパンダーは必要なだけスペースを取る機会が与えられ、その中のWrapPanelは、制約がないため、すべてのアイテムを1つの垂直線に配置するだけです。

于 2011-12-13T10:26:44.677 に答える
2

ラップを垂直にするWrapPanelには、それを制限する必要がありますHeight

たとえば、WrapPanel定義を作成した場合

<WrapPanel Orientation="Vertical" Height="100" />

あなたはあなたが望む方法でアイテムをラッピングするでしょう.

ここに画像の説明を入力

また、ScrollViewerデフォルトでは水平スクロールバーは表示されません。それらを有効にするには、HorizontalScrollBarVisibility

<ScrollViewer CanContentScroll="False" HorizontalScrollBarVisibility="Auto">
    <ItemsControl ItemsSource="{Binding CheckGroups}" ItemTemplate="{StaticResource CheckGroupsTemplate}" />
</ScrollViewer>
于 2011-12-13T21:03:34.517 に答える
0

私を正しい方向に導いてくれた Jefim と Rachel に感謝します。私にとって欠落しているリンクは、Jefim が指摘したように、実際には CheckGroup DataTemplate の MaxHeight でした。

ここで、MaxHeight をウィンドウの実際の高さから高さを引いた値に設定して、他のグループが表示されたままになるようにします。

これは汚い解決策のように見えるかもしれませんが、いくつかの気の利いた wpf ブラシを使用すると、見栄えがよくなり、動作が私の期待に非常に近くなります!

私が望んでいた動作になるようにコードを変更します。

MainWindow.xaml

<Window 
    x:Class="VerticalWrapPanel.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:controls="clr-namespace:VerticalWrapPanel" 
    xmlns:converters="clr-namespace:VerticalWrapPanel" 
    Title="MainWindow" 
    Height="350"
    Width="525" 
    Loaded="Window_Loaded"
    x:Name="MyWindow">

    <Window.Resources>
        <converters:ActualHeightReduce x:Key="ActualHeightReduce" />
        <DataTemplate x:Key="CheckGroupsTemplate">
            <controls:CheckGroupControl MaxHeight="{Binding ElementName=MyWindow, Path=ActualHeight, Converter={StaticResource ActualHeightReduce}}" />
        </DataTemplate>
    </Window.Resources>

    <ScrollViewer CanContentScroll="False">
        <ItemsControl ItemsSource="{Binding CheckGroups}" ItemTemplate="{StaticResource CheckGroupsTemplate}" />
    </ScrollViewer>
</Window>

MainWindow.xaml.cs への追加 (名前空間 VerticalWrapPanel 内)

public class ActualHeightReduce : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null || string.IsNullOrEmpty(value.ToString()))
            return value;

        double vValue;

        if (Double.TryParse(value.ToString(), out vValue))
        {
            return vValue - 75;
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

また、CheckGroupControl.xaml には適切な水平スクロールがあります。

<UserControl
    x:Class="VerticalWrapPanel.CheckGroupControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:controls="clr-namespace:VerticalWrapPanel"
    x:Name="GroupControl">

    <UserControl.Resources>
        <DataTemplate x:Key="CheckTemplate">
            <controls:CheckControl />
        </DataTemplate>
    </UserControl.Resources>

    <Expander BorderBrush="Black" Header="TEST" IsExpanded="{Binding ElementName=GroupControl,     Path=IsExpanded}">
        <ItemsControl ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" ItemsSource="{Binding Checks}" ItemTemplate="{StaticResource CheckTemplate}">
            <ItemsControl.Template>
                <ControlTemplate>
                    <ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
                        <ItemsPresenter />
                    </ScrollViewer>
                </ControlTemplate>
            </ItemsControl.Template>
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Vertical" IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Expander>
</UserControl>

そしてもちろん、CheckControl のラップパネルの方向は引き続き垂直に設定する必要があります;)

于 2011-12-13T23:40:26.660 に答える