Связывание WPF с шириной столбца сетки - PullRequest
8 голосов
/ 13 ноября 2008

Я пытаюсь связать DependancyProperty в одном из моих пользовательских контроллеров со свойством Width Column в Grid.

У меня есть код, подобный этому:

<Grid x:Name="MyGridName">
    <Grid.ColumnDefinitions>
        <ColumnDefinition x:Name="TitleSection" Width="100" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>...</Grid.RowDefinitions>

    <GridSplitter x:Name="MyGridSplitter" Grid.Row="0" Grid.Column="0" ... />
</Grid>

В отдельном пользовательском контроле я определил следующее DependancyProperty.

public static readonly DependencyProperty TitleWidthProperty = DependencyProperty.Register("TitleWidth", typeof(int), typeof(MyUserControl));

public int TitleWidth
{
    get { return (int)base.GetValue(TitleWidthProperty); }
    set { base.SetValue(TitleWidthProperty, value); }
}

Я создаю экземпляры Usercontrol в коде, поэтому у меня есть оператор привязки, подобный следующему:

MyUserControl Cntrl = new MyUserControl(/* Construction Params */);
BindingOperations.SetBinding(Cntrl , MyUserControl.AnotherProperty, new Binding { ElementName = "objZoomSlider", Path = new PropertyPath("Value"), Mode = BindingMode.OneWay });
BindingOperations.SetBinding(Cntrl , MyUserControl.TitleWidthProperty, new Binding { ElementName = "TitleSection", Path = new PropertyPath("ActualWidth"), Mode = BindingMode.OneWay });
/* Other operations on Cntrl */

Первая определенная привязка работает фантастически, хотя это привязка к реальному UIElement (в данном случае к ползунку), но привязка к «TitleSection» (который является ColumnDefinition, определенным в Grid) не выполняется. Установка точки останова в коде и выполнение наблюдения за «TitleSection» возвращает ожидаемый объект.

Я начинаю подозревать, что x: Name'd ColumnDefinition не может быть привязан к. Кто-нибудь может подсказать, как я могу привязаться к изменяющейся ширине первого столбца в моей сетке?

РЕДАКТИРОВАТЬ # 1 - Чтобы ответить на комментарии

Привязка данных «терпит неудачу» в том смысле, что с точкой останова, установленной в установщике для свойства TitleWidth, и с использованием элемента управления GridSplitter для изменения размера первого столбца точка останова никогда не будет достигнута. Кроме того, код, который я ожидаю, будет запущен, когда изменения DependancyProperty TitleWidth не будут выполнены.

Пользовательский контроль создается и добавляется в панель стека в сетке в функции Window_Loaded. Я ожидаю, что Grid будет отображаться к моменту создания пользовательских контролей. Конечно, элемент x: Name'd TitleSection является наблюдаемым и имеет значение 100, когда они создаются / до того, как происходит привязка.

РЕДАКТИРОВАТЬ # 2 - Возможно, что-то делать с этим?

Я нюхал страницы MSDN для документации Grid ColumnDefinition и наткнулся на GridLength () , но я не могу понять, как я могу использовать это в выражении привязки , Я не могу использовать связанный GridLengthConverter в качестве преобразователя в коде привязки, поскольку он не является производным от IValueConverter.

Я склоняюсь к каким-либо привязкам к свойству ActualWidth одной из ячеек в объекте Grid. Это не так чисто, как привязка к определению столбца, но сейчас я не могу заставить это работать.

Ответы [ 3 ]

11 голосов
/ 13 ноября 2008

Ну, у меня есть немного работы, я объясню, как для будущих поколений:

По сути, у меня есть многострочная сетка из 2 столбцов с разделителем, выровненным по правому краю в первом столбце, чтобы пользователь мог изменить его размер, если содержимое, которое он содержит, требует больше места. Чтобы усложнить ситуацию, у меня есть пользовательский элемент управления, загружаемый программно в некоторые из строк, у которого для визуализации используется значение columnSpan, равное 2 (содержимое «сливается» из одной ячейки в следующую).

Когда размер первого столбца изменяется, мне нужно, чтобы это было отражено в пользовательском контроле. Сначала я попытался привязаться к ColumnDefinition, но он действительно не играл в мяч.

Как я исправил / Kludged это

В запасной ячейке в первом столбце я добавил <Label> с именем x: Name, чтобы сделать его доступным. Поскольку он находится в ячейке, он имеет свойства по умолчанию «Растянуть» и полностью заполняет ячейку. Он изменяется при изменении размера столбца с использованием сплиттера. Привязка к свойству Label ActualWidth означает, что изменения размера столбца правильно передаются в DependancyProperty в моем columnSpanned usercontrol.

Мысли

Очевидно, что несмотря на то, что ColumnDefinition имеет свойство ActualWidth, когда оно изменяется, оно, похоже, не вызывает внутреннее событие PropertyChanged (или это мое лучшее предположение). Это может быть ошибкой или намеренно, но для меня это означает, что мне пришлось использовать менее чистое решение.

3 голосов
/ 13 ноября 2008

Вы пытались настроить привязку в xaml, у вас должно работать следующее:

<ColumnDefinition 
    x:Name="TitleSection" 
    Width="{Binding 
                Path=TitleWidth, 
                RelativeSource={RelativeSource AncestorType=MyUserControl}}" 
    />

В противном случае, если посмотреть на код привязки, который вы указали, он выглядит неверно, целью привязки должен быть столбец сетки, а источником - свойство зависимости.

Эквивалентный код для вышеупомянутого xaml:

BindingOperations.SetBinding(TitleSection, ColumnDefinition.WidthProperty,
    new Binding()
    {
        RelativeSource= new RelativeSource(RelativeSourceMode.FindAncestor, typeof(MyUserControl),1),
        Path = new PropertyPath("TitleWidth"),
    });

В связанной заметке использование GridSplitter и привязка свойства Width являются взаимоисключающими. Как только вы измените размер столбца с помощью разделителя, ваша привязка будет заменена значением из разделителя.

Это похоже на то, что вы испытаете, обновляя любое свойство, являющееся целью привязки. Когда вы устанавливаете целевое значение непосредственно в коде, вы по существу заменяете объект привязки указанным вами значением.

2 голосов
/ 06 ноября 2014

ColumnDefinition.Width не является целым числом - это GridLength. Вы не можете привязать GridLength напрямую к Integer, вам нужен конвертер.

Это также причина, почему вы не можете привязать какое-либо свойство Width элемента управления (double) к свойству Width ColumnDefinition (GridLength) без конвертера.

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