WPF ListBox Width Binding [дубликат]

Попробуйте поместить document.getElementById в setTimeout()

Например.

setTimeout(function(){
    console.log(document.getElementById('whatever'));
}, 100);

Если это сработает, тогда это просто проблема синхронизации.

56
задан Eric Haskins 25 July 2013 в 07:16
поделиться

5 ответов

Если вы хотите использовать Grid, вам нужно изменить ColumnDefinition s следующим образом:

    <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" заполнит оставшееся пространство.

132
ответ дан Dave Clemmer 20 August 2018 в 11:17
поделиться
  • 1
    Та приятель. Поработал в поисках помощи, и это было по первой ссылке. Хороший :) – Binary Worrier 21 March 2009 в 00:20
  • 2
    Это НЕ делает панель данных заполняющей ширину списка. – Kevin Berridge 11 May 2009 в 13:00
  • 3
    Вам нужно использовать HorizontalContentAlignment = & quot; Stretch & quot; в списке, как указано ниже – cbeuker 18 February 2011 в 00:42
  • 4
    Мне нравится простота такого подхода. Он не только гарантирует, что маленькие элементы заполняют ширину, она гарантирует, что элементы, содержимое которых будет очень широк, ограничены шириной списка. – Mal Ross 19 August 2011 в 09:38
  • 5
    @Eric Haskins У меня такая же проблема для элемента управления Pivot для Windows Phone (<controls:Pivot.ItemTemplate><DataTemplate /></controls:Pivot.ItemTemplate>). Но где я должен поместить этот код? Я пробовал некоторые, но я не мог понять это. – SynerCoder 4 October 2012 в 16:30
  • 6
    Заметка для пользователей Windows Phone - это не сработает; свойство переопределяется элементом ItemContainerStyle ListBox. Чтобы заставить его работать, см. Ответ Габриэля Монгеона: stackoverflow.com/questions/838828/… – Carlos P 11 November 2012 в 12:11
  • 7
    Именно то, что я искал: заполнение ширины при слишком малом и ограничение ширины при слишком большом размере. – Lensflare 7 January 2016 в 13:43
  • 8
    Я просто заметил, что это решение приводит к тому, что ширина ListBox постоянно будет немного меньше ширины элемента, что сокращает количество элементов и активирует горизонтальную полосу прокрутки в нижней части списка. Я исправил это, явно отключив горизонтальную прокрутку. – Lensflare 7 January 2016 в 14:10
  • 9
    то же работает с ItemsControl – Simon_Weaver 23 January 2017 в 10:59
  • 10
    Это должно быть одним из самых раздражающих хакеров UI. Почему это не задано по умолчанию? Smh. – Matthew S 14 May 2018 в 17:17
132
ответ дан Dave Clemmer 31 October 2018 в 09:16
поделиться

Ответ Тэке работает хорошо, и, как ответ ванкутерромни, вы можете отключить горизонтальную полосу прокрутки, чтобы избавиться от несоответствия раздражающего размера. Однако, если вы хотите, чтобы лучшее из обоих миров, - чтобы удалить полосу прокрутки, когда она не нужна, но автоматически включается, когда ListBox становится слишком маленьким, вы можете использовать следующий конвертер:

/// <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 в соответствии с желаемыми значениями max / min, а также смещением для устранения этого раздражающего несоответствия в размере 2 пикселя, как указано в других ответах:

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

Затем используйте конвертер в привязке Width:

<Grid.Width>
    <Binding Path="ActualWidth" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ScrollContentPresenter}}" Converter="{StaticResource conDoubleLimiter}"  />
</Grid.Width>
0
ответ дан BCA 20 August 2018 в 11:17
поделиться

Grid должен по умолчанию принимать всю ширину ListBox, потому что по умолчанию ItemsPanel для него VirtualizingStackPanel. Я предполагаю, что вы не изменили ListBox.ItemsPanel.

Возможно, если вы избавились от середины ColumnDefinition (остальные по умолчанию "*") и поместите HorizontalAlignment="Left" на ваш WrapPanel и HorizontalAlignment="Right" на ListBox для телефонных номеров. Возможно, вам придется немного изменить это ListBox, чтобы получить номера телефонов с еще большим выравниванием по правому краю, например, для них DataTemplate.

1
ответ дан Joel B Fant 20 August 2018 в 11:17
поделиться

Метод в ответе Тэке заставляет горизонтальную полосу прокрутки. Это можно устранить, добавив конвертер, чтобы уменьшить ширину сетки по ширине элемента управления вертикальной полосой прокрутки.

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>
0
ответ дан Kevin Hilt 20 August 2018 в 11:17
поделиться
  • 1
    Это должно быть сделано с помощью функции HorizontalContentAlignment. – Ed Plunkett 22 June 2017 в 22:39
  • 2
    @EdPlunkett Вы имеете в виду HorizontalContentAlignment в ListBox, как в принятом ответе Эрика Хаскинса? Если это так, я не мог заставить это работать, поэтому я перешел на этот худший метод. – Kevin Hilt 23 June 2017 в 19:26
  • 3
    OMG, правильный общий ответ даже не на этой странице. В этом ответе: stackoverflow.com/a/2924249/424129 - установите HorizontalContentAlignment="Stretch" в элементе списка элемент в списке, который вы делаете через ListBox.ItemContainerStyle. – Ed Plunkett 23 June 2017 в 19:29
  • 4
    @EdPlunkett Я столкнулся с этим ответом, но, если я не буду игнорировать что-то простое, это также не работает для меня. Возможно, это связано с тем, что я использую шаблон данных. – Kevin Hilt 23 June 2017 в 19:54
Другие вопросы по тегам:

Похожие вопросы: