2012-01-25 2 views
3

У меня есть это довольно простое окно с сеткой, содержащей два столбца, TextBlock и TextBox.Как настроить панель WPF Grid таким образом?

enter image description here

Что мне нужно, чтобы установить столбец 0 автоматически размер его содержание и иметь столбец 1 (содержание), чтобы быть в 4 раза размер столбца 0.

Как я могу сделай это. Я создам потомок Grid, если это решение, потому что мне действительно нужна эта функция.

Редактировать: Другие пояснения. Содержимое столбца 0 не будет меняться во время выполнения, поэтому размер столбца 0 или столбца 1 не должен изменяться во время выполнения. Сетка будет дочерним элементом окна, настроенного с SizeToContent="WidthAndHeight", поэтому дополнительное пространство не должно существовать.

Ответ на Дмитрия: Я попробовал то, что вы говорите со следующим кодом, и она не работает вообще:

<Window x:Class="UnderstandSizing.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Title="Window1" 
SizeToContent="WidthAndHeight" > 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width=".25*" /> 
     <ColumnDefinition Width=".75*" /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <TextBlock Grid.Column="0" Text="THIS IS THE LABEL:" /> 
    <TextBox Grid.Column="1" Text="content" /> 
</Grid> 
</Window> 

Последнее редактирование: Почему, черт возьми, я (или кто) это нужно?

Одна из приятных вещей WPF - это его способность работать без фиксированных размеров? Если вы нарушены, и у вас больше размер шрифта, все будет выглядеть нормально. Если вы переводите свой пользовательский интерфейс на другой язык, для которого требуется размер x2, все будет выглядеть нормально. Если у вас разные настройки PPI, все будет выглядеть нормально.

Но я не хочу видеть, как экраны меняют свой размер во время выполнения, потому что пользователи к этому не привыкли. Вот почему я хочу установить размер полей ввода кратным знакомую. Если я дам ячейке ярлыка размеру до того, что ей нужно, а затем я установил ячейку содержимого в множитель метки, я получу преимущества автосогласования с поведением, которое пользователи ожидают наличия экранов с фиксированным размером (если они не изменят его размер Это).

+0

вы хотите внешнего размер сетки, чтобы расширить ли, когда размер увеличивается содержание столбца 1? Или у вас есть заданное пространство, внутри которого должна оставаться сетка? Или ширина столбца 1 постоянна и известна во время компиляции? –

+0

Один вопрос: если вы хотите, чтобы столбец 1 в четыре раза превышал размер столбца 0, что происходит с оставшимся пространством? Или, что вам нужно, если ширина столбца 0 + 4 раза ширина столбца 0 превышает доступное пространство? – dowhilefor

+0

Пробовал ли вы использовать проценты - http://www.tanguay.info/web/index.php?pg=codeExamples&id=36 –

ответ

6

Вы можете использовать привязки по сетке колонн:

<Grid.ColumnDefinitions> 
    <ColmunDefinition Width="Auto" x:Name="firstCol"/> 
    <ColumnDefinition Width="{Binding ActualWidth, ElementName=firstCol, Converter={StaticResource MultiplyConverter}, ConverterParameter=4}" /> 
</Grid.ColumnDefinitions> 

Затем преобразователь:

public class MultiplyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     double originalValue; 
     double multiplier; 
     if (value != null && parameter != null && 
      double.TryParse(value.ToString(), out originalValue) && 
      double.TryParse(parameter.ToString(), out multiplier)) //Can be lots of things: sentinel object, NaN (not a number)... 
     { 
      return originalValue * multiplier; 
     } 
     else return Binding.DoNothing; 
    } 

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

Вы также можете написать прикрепленное свойство для столбцов сетки.

+0

Выглядит как выполнимый. Можете ли вы немного объяснить свойство прикрепленного имущества? Я не понимаю, что вы имеете в виду. –

+0

Вы можете просто проверить 'if (value double)', тогда он не может быть нулевым и не нуждается в анализе. Кроме того, взгляните на [Binding.DoNothing] (http://msdn.microsoft.com/en-us/library/system.windows.data.binding.donothing.aspx). +1 для использования ConverterParameter для гибкости ... –

+0

Зависит от того, насколько вы продвинуты в WPF, потому что это было бы немного сложно реализовать. Я могу думать о нескольких способах, но я думаю, вы должны прочитать о прикрепленных свойствах (http://msdn.microsoft.com/en-us/library/ms749011.aspx). Он позволяет добавлять свойство в UIElement и манипулировать его значениями с помощью обратных вызовов. –

0

Взято из: http://www.tanguay.info/web/index.php?pg=codeExamples&id=36

идея заключается в использовании:

Update 2 - полный XAML писал (ум поведение детей сетке в):

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width=".25*" /> 
       <ColumnDefinition Width=".75*" /> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="Auto" /> 
      </Grid.RowDefinitions> 
      <Grid Background="Yellow" Grid.Column="0"> 
       <TextBlock Text="THIS IS THE LABEL:" /> 
      </Grid> 
      <Grid Background="Blue" Grid.Column="1"> 
       <TextBox Background="Transparent" Text="content" /> 
      </Grid> 

     </Grid> 

    </Grid> 
</Window> 

Я только что проверил это и сработало.

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

Другая проблема - в общем, макеты WPF предназначены для защиты, то есть если ребенок вашей сетки нельзя сжимать - обычно ваша логика компоновки должна размещаться для нее, как правило, путем приостановки некоторых правил компоновки.

+0

Это, конечно, не отвечает на вопрос. Как изменить ширину сетки при изменении размера содержимого столбца 0? –

+0

о да? вы попробовали? –

+0

Вопрос в следующем: Вы * попробовали?Ваша сетка будет всегда расширяться по всей ширине, а столбец 0 обычно не имеет точной ширины его содержимого. –

0

Edit:

Если размеры известны во время компиляции, не было бы проще установить ширину вручную?


Вы можете использовать BindingConverter для этого, я бы с отдельными элементами в горизонтальной StackPanel (смотрите, что ширина StackPanel является достаточно большим для вашего содержания):

Вот очищенный код.

MainWindow.xaml:

<!-- define xmlns:local="clr-namespace:YourAppNamespace" --> 
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left"> 
    <StackPanel.Resources> 
     <local:WidthConverter x:Key="wc" /> 
    </StackPanel.Resources> 
    <Grid Background="Gray" x:Name="col1"> 
     <TextBlock Text="blub"/> 
    </Grid> 
    <Grid Background="Orange" Width="{Binding ElementName=col1, Path=ActualWidth, Converter={StaticResource ResourceKey=wc}}"> 
     <Label Content="bla"></Label> 
    </Grid> 
</StackPanel> 

MainWindow.xaml.cs:

public class WidthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (!(value is double)) 
     { 
      return Binding.DoNothing; 
     } 
     return ((double)value) * 4.0; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Это не будет работать для целых столбцов, это просто между Label и TextBlock. –

+0

Я не знаю лучшего способа создания изменчивого, безответственного пользовательского интерфейса, чем тот, который вы разместили. вы используете его в своих проектах? –

+0

@Baboon: Хорошо, изменил его, теперь сетки зависят друг от друга. –

0

Как я понимаю, вы пытаетесь разметить ярлык (текстовый блок) и соответствующее поле ввода для него. В качестве индикатора вы должны сначала увидеть Beth Massi'sWindows Client video на простой форме ввода данных, которая находится на разработке формы data entry, но выкладка также продемонстрирована очень хорошо.

Особенно наблюдать, как она выкладывает управления на WPF окна с помощью дизайнера, окно свойств и XAML, и тогда я думаю, вы не должны иметь потребность в первом столбце, чтобы быть Auto размера и второго столбца 4* первой колонка.

EDIT: В соответствии с обновлением в вопросе, я отправляю возможное решение, как показано ниже:

  1. код XAML файл (обратите внимание на SizeToContent использование в Window и что привязка к ActualWidth собственности для Textbox контроль):

    <Window x:Class="GridTest.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:local="clr-namespace:GridTest" 
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
        Title="MainWindow" 
        d:DesignHeight="350" 
        d:DesignWidth="525" 
        SizeToContent="WidthAndHeight" 
        mc:Ignorable="d"> 
    <Grid> 
        <Grid.Resources> 
         <local:FourWidthConverter x:Key="FourWidthConv" /> 
        </Grid.Resources> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="Auto" /> 
         <ColumnDefinition Width="*" /> 
        </Grid.ColumnDefinitions> 
        <TextBlock Name="tb" 
           Grid.Column="0" 
           Text="Auto Text, change at design time to see changes in Width" /> 
        <TextBox Name="tx" 
          Grid.Column="1" 
          Width="{Binding ElementName=tb, 
              Path=ActualWidth, 
              Converter={StaticResource FourWidthConv}}" 
          Text="4 * col 1 width displaying Text in SizetoContentWindow" /> 
    </Grid> 
    </Window> 
    
  2. .Xaml.cs файл кода (Обратите внимание на конвертер здесь):

    using System.Windows; 
    using System.Windows.Data; 
    
    namespace GridTest 
    { 
        /// <summary> 
        /// Interaction logic for MainWindow.xaml 
        /// </summary> 
        public partial class MainWindow : Window 
        { 
         public MainWindow() 
         { 
          InitializeComponent(); 
         } 
        } 
    
        public class FourWidthConverter : IValueConverter 
        { 
         public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
         { 
          return 4 * (double)value; 
         } 
    
         public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
         { 
          throw new System.NotImplementedException(); 
         } 
        } 
    } 
    
+0

прочитал мое редактирование, чтобы понять, почему мне или кому-то может понадобиться эта функция. –

+0

@SoMoS Я отредактировал свой ответ и разместил возможное решение, см. EDIT .. – VS1

+0

@SoMoS Вероятно, вам нужно будет реализовать этот код внутри пользовательского элемента управления, а не окна для повторного использования такого типа функций. – VS1