Frage

Ich habe eine ListBox DataTemplate in WPF. Ich mag ein Element dicht an der linken Seite des ListBox und ein anderes Elements sein und fest an der rechten Seite zu sein, aber ich kann nicht herausfinden, wie dies zu tun.

Bisher habe ich eine Grid mit drei Spalten haben, haben die linken und richtigen Inhalt und das Zentrum ist ein Platzhalter mit ihm Breite Set zu „*“. Wo soll ich denn falsch?

Hier ist der Code:

<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>
War es hilfreich?

Lösung

Ich hatte auch setzen:

HorizontalContentAlignment="Stretch"

auf der enthaltenden ListBox.

Andere Tipps

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

Ok, hier ist das, was Sie haben:

Spalte 0: WrapPanel
Spalte 1: Nichts
Spalte 2: ListBox

Es klingt wie Sie WrapPanel am linken Rand wollen, ListBox am rechten Rand und Raum zu übernehmen, was in der Mitte übrig geblieben ist.

Die einfachste Weg, dies zu tun, ist eigentlich eine DockPanel zu verwenden, keinen Grid.

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

Dies sollte leeren Raum zwischen dem WrapPanel verlassen und dem ListBox.

Die Ausweitung Taeke Antwort, die ScrollViewer.HorizontalScrollBarVisibility="Hidden" für eine ListBox Einstellung des Kindes Kontrolle ermöglicht es den Eltern Breite nehmen und nicht die Bildlaufleiste zeigen müssen.

<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 >

Die Grid standardmäßig sollte die gesamte Breite des ListBox, weil der Standard ItemsPanel denn es ist ein VirtualizingStackPanel aufzunehmen. Ich gehe davon aus, dass Sie nicht geändert ListBox.ItemsPanel.

Vielleicht, wenn Sie von der Mitte ColumnDefinition losgeworden (die anderen sind Standard "*") und setzen HorizontalAlignment="Left" auf WrapPanel und HorizontalAlignment="Right" auf dem ListBox für Telefonnummern. Sie können von diesem ListBox ein wenig zu verändern haben die Telefonnummern noch rechtsbündig, wie die Schaffung eines DataTemplate für sie zu erhalten.

Wenn Sie eine Grid verwenden möchten, dann müssen Sie Ihre ColumnDefinitions ändern werden:

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

Wenn Sie keinen Grid verwenden müssen, dann könnten Sie eine DockPanel verwenden:

    <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>

Beachten Sie die TextBlock am Ende. Jede Kontrolle ohne "DockPanel.Dock" definiert wird den verbleibenden Raum füllen.

Taeke Antwort gut funktioniert, und wie pro vancutterromney Antwort können Sie die horizontale Bildlaufleiste deaktivieren, das lästigen size mismatch loszuwerden. Wenn Sie jedoch das Beste aus beiden Welten tun wollen - die Bildlaufleiste zu entfernen, wenn sie nicht benötigt wird, sondern es automatisch aktiviert, wenn die List-Box zu klein wird, können Sie den folgenden Konverter verwenden:

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

Dann ist es in XAML definieren, je nach den gewünschten max / min-Werten als auch ein Versatz mit diesem lästigen 2-Pixelgrße Mismatch zu behandeln, wie in den anderen Antworten genannt:

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

Verwenden Sie dann den Konverter in der Breite Bindung:

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

Das Verfahren in Taeke Antwort erzwingt eine horizontale Bildlaufleiste. Dies kann durch Zugabe eines Wandlers befestigt werden das Netz der Breite durch die Breite der vertikalen Bildlaufsteuerung zu reduzieren.

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

Fügen Sie einen Namespace auf den Wurzelknoten Ihrer XAML.

xmlns:converters="clr-namespace:Converters"

und aktualisieren Sie die Rasterweite des Wandlers verwendet werden.

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{converters:ListBoxItemWidthConverter}"/>
</Grid.Width>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top