كيف يمكنني جعل WPF البيانات قالب ملء كامل عرض مربع القائمة?

StackOverflow https://stackoverflow.com/questions/135375

سؤال

لدي ListBox DataTemplate في WPF.أريد عنصر واحد أن تكون ضيقة ضد الجانب الأيسر من ListBox عنصر آخر أن تكون ضيقة ضد الجانب الأيمن, ولكن أنا لا يمكن معرفة كيفية القيام بذلك.

حتى الآن لدي Grid مع ثلاثة أعمدة اليمين واليسار منها المحتوى من مركز نائبا مع عرض مجموعة "*".أين أنا أين الخطأ ؟

هنا هو رمز:

<DataTemplate x:Key="SmallCustomerListItem">
    <Grid HorizontalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <WrapPanel HorizontalAlignment="Stretch" Margin="0">
            <!--Some content here-->
            <TextBlock Text="{Binding Path=LastName}" TextWrapping="Wrap" FontSize="24"/>
            <TextBlock Text=", " TextWrapping="Wrap" FontSize="24"/>
            <TextBlock Text="{Binding Path=FirstName}" TextWrapping="Wrap" FontSize="24"/>

        </WrapPanel>
        <ListBox ItemsSource="{Binding Path=PhoneNumbers}" Grid.Column="2" d:DesignWidth="100" d:DesignHeight="50"
     Margin="8,0" Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False" HorizontalAlignment="Stretch"/>
    </Grid>
</DataTemplate>
هل كانت مفيدة؟

المحلول

كما أن مجموعة:

HorizontalContentAlignment="Stretch"

على تحتوي ListBox.

نصائح أخرى

<Grid.Width>
    <Binding Path="ActualWidth" 
             RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" />
</Grid.Width>

حسنا هذا ما لديك:

العمود 0: WrapPanel
العمود 1:لا شيء
العمود 2: ListBox

يبدو أنك تريد ، WrapPanel على الحافة اليسرى ، ListBox على الحافة اليمنى و الفضاء أن تأخذ ما تبقى في الوسط.

أسهل طريقة للقيام بذلك هو في الواقع استخدام DockPanel, لا Grid.

<DockPanel>
    <WrapPanel DockPanel.Dock="Left"></WrapPanel>
    <ListBox DockPanel.Dock="Right"></ListBox>
</DockPanel>

هذا يجب أن تترك مساحة فارغة بين WrapPanel و ListBox.

تمديد Taeke الجواب ، ووضع ScrollViewer.HorizontalScrollBarVisibility="Hidden" عن ListBox يسمح للطفل التحكم لاتخاذ الوالد العرض وليس لديها شريط التمرير تظهر.

<ListBox Width="100" ScrollViewer.HorizontalScrollBarVisibility="Hidden">                
    <Label Content="{Binding Path=., Mode=OneWay}" HorizontalContentAlignment="Stretch" Height="30" Margin="-4,0,0,0" BorderThickness="0.5" BorderBrush="Black" FontFamily="Calibri" >
        <Label.Width>
            <Binding Path="Width" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}" />
        </Label.Width>
    </Label>
</ListBox >

على Grid يجب افتراضيا يستغرق عرض كل ListBox لأن الافتراضي ItemsPanel هو VirtualizingStackPanel.أنا على افتراض أن لديك لا تغيرت ListBox.ItemsPanel.

ربما لو كنت حصلت على التخلص من الوسط ColumnDefinition (الآخرين هي الافتراضية "*") ، ووضع HorizontalAlignment="Left" على WrapPanel و HorizontalAlignment="Right" على ListBox للحصول على أرقام الهاتف.قد تضطر إلى تغيير ذلك ListBox قليلا للحصول على أرقام الهاتف أكثر محاذاة إلى اليمين ، مثل إنشاء DataTemplate بالنسبة لهم.

إذا كنت ترغب في استخدام Grid, ثم كنت بحاجة إلى تغيير ColumnDefinitionأن تكون:

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

إذا كنت لا تحتاج إلى استخدام Grid, ثم هل يمكن استخدام DockPanel:

    <DockPanel>
        <WrapPanel DockPanel.Dock="Left">
            <!--Some content here-->
            <TextBlock Text="{Binding Path=LastName}" TextWrapping="Wrap" FontSize="24"/>
            <TextBlock Text=", " TextWrapping="Wrap" FontSize="24"/>
            <TextBlock Text="{Binding Path=FirstName}" TextWrapping="Wrap" FontSize="24"/>
        </WrapPanel>
        <ListBox DockPanel.Dock="Right" ItemsSource="{Binding Path=PhoneNumbers}" 
 Margin="8,0" Background="Transparent" BorderBrush="Transparent" IsHitTestVisible="False"/>
        <TextBlock />
    </DockPanel>

لاحظ TextBlock في نهاية المطاف.أي التحكم لا "DockPanel.Dock" تعريف ملء المساحة المتبقية.

Taeke الجواب يعمل بشكل جيد ، كما في vancutterromney الجواب يمكنك تعطيل شريط التمرير الأفقي إلى التخلص من مزعج عدم تطابق حجم.ومع ذلك ، إذا كنت تريد أفضل من كلا العالمين--إزالة شريط التمرير عند عدم الحاجة إليه ، ولكن يكون ذلك تلقائيا تمكين عند ListBox يصبح صغير جدا, يمكنك استخدام ما يلي converter:

/// <summary>
/// Value converter that adjusts the value of a double according to min and max limiting values, as well as an offset. These values are set by object configuration, handled in XAML resource definition.
/// </summary>
[ValueConversion(typeof(double), typeof(double))]
public sealed class DoubleLimiterConverter : IValueConverter
{
    /// <summary>
    /// Minimum value, if set. If not set, there is no minimum limit.
    /// </summary>
    public double? Min { get; set; }

    /// <summary>
    /// Maximum value, if set. If not set, there is no minimum limit.
    /// </summary>
    public double? Max { get; set; }

    /// <summary>
    /// Offset value to be applied after the limiting is done.
    /// </summary>
    public double Offset { get; set; }

    public static double _defaultFailureValue = 0;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || !(value is double))
            return _defaultFailureValue;

        double dValue = (double)value;
        double minimum = Min.HasValue ? Min.Value : double.NegativeInfinity;
        double maximum = Max.HasValue ? Max.Value : double.PositiveInfinity;
        double retVal = dValue.LimitToRange(minimum, maximum) + Offset;
        return retVal;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

ثم تحديد ذلك في XAML وفقا المطلوب ماكس/دقيقة القيم ، وكذلك إزاحة للتعامل مع هذا مزعج 2-بكسل حجم التفاوت كما ورد في إجابات أخرى:

<ListBox.Resources>
    <con:DoubleLimiterConverter x:Key="conDoubleLimiter" Min="450" Offset="-2"/>
</ListBox.Resources>

ثم استخدام المحول في عرض ملزم:

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{StaticResource conDoubleLimiter}"  />
</Grid.Width>

طريقة في Taeke الجواب القوات شريط التمرير الأفقي.وهذا يمكن أن تكون ثابتة عن طريق إضافة محول للحد من الشبكة عرض من عرض شريط التمرير العمودي التحكم.

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Markup;

namespace Converters
{
    public class ListBoxItemWidthConverter : MarkupExtension, IValueConverter
    {
        private static ListBoxItemWidthConverter _instance;

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return System.Convert.ToInt32(value) - SystemParameters.VerticalScrollBarWidth;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            return _instance ?? (_instance = new ListBoxItemWidthConverter());
        }
    }
}

إضافة مساحة إلى عقدة الجذر الخاص بك XAML.

xmlns:converters="clr-namespace:Converters"

وتحديث شبكة العرض إلى استخدام محول.

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{converters:ListBoxItemWidthConverter}"/>
</Grid.Width>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top