Вопрос

Я пытаюсь связать DependancyProperty в одном из моих пользовательских элементов управления для Width свойство a 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>

В отдельном Usercontrol у меня есть следующее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 */

Первая определенная привязка работает фантастически, хотя это привязка к фактическому элементу пользовательского интерфейса (в данном случае к слайдеру), но привязка к "TitleSection" (который является определением столбца, определенным в сетке) завершается с ошибкой.Ввод точки останова в код и выполнение просмотра "TitleSection" возвращает ожидаемый объект.

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

ПРАВКА № 1 - Для ответа на комментарии

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

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

ПРАВКА № 2 - Возможно, это как-то связано с этим?

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

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

Это было полезно?

Решение

Что ж, у меня тут кое-что получилось, я объясню, как это сделать, для будущих поколений:

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

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

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

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

Мысли

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

Другие советы

Вы пытались настроить привязку в 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 являются взаимоисключающими. Как только вы измените размер столбца с помощью разделителя, ваша привязка будет заменена значением из разделителя.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top