Передать управление привязке по значению - PullRequest
0 голосов
/ 18 июня 2020

У меня есть конвертер, который я использую для определения размера дочернего элемента на основе размера его контейнера (родительского).

<Setter Property="Width" Value="{Binding ActualWidth, ElementName=rowsContainer, 
                                 Converter={StaticResource sizer}}"/>
public class CellSizeConverter : IValueConverter
{
    private readonly int _maxNum = 7;
    private readonly int _margin = 0;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        double width = (double)value;
        return (width / _maxNum) - _margin;
    }
}

Это работает, и когда я изменяю размер своего окна, размер компонентов меняется. Ура!

Я также хочу учитывать высоту, поэтому я попытался передать сам элемент управления и получить его свойства внутри конвертера:

<Setter Property="Width" Value="{Binding ElementName=rowsContainer, Converter={StaticResource sizer}}"/>
public class CellSizeConverter : IValueConverter
{
    private readonly int _maxNum = 7;
    private readonly int _margin = 0;

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
        {
            return null;
        }
        ItemsControl rowsContainer = (ItemsControl)value;
        return (rowsContainer.ActualWidth / _maxNum) - _margin;
    }
}

Однако, когда я это делаю, размер никогда не меняется. Кажется, что управление передается конвертеру один раз, но никогда не обновляется. Я предполагаю, что это как-то связано с передачей по ссылке, а не по значению. Или что-то в этом роде.

Я знаю, что могу передать несколько значений в конвертер, используя MultiBinding и IMultiValue Converter, но поскольку все значения, которые мне нужны, уже заключены в красивый маленький объект ( элемент управления) было бы намного чище в моем xaml, если бы просто привязать его таким образом.

Как передать элемент управления, чтобы он обновлялся?

Ответы [ 2 ]

1 голос
/ 18 июня 2020

Кажется, что управление передается конвертеру один раз, но никогда не обновляется. Я предполагаю, что это как-то связано с передачей по ссылке, а не по значению.

Обновления свойств в WPF не являются magi c, код должен явно вызывать WPF, чтобы сообщить ему, что значение было обновлено.

Когда вы привязываете ActualWidth, на самом деле это свойство зависимости, которое имеет измененное событие, которое WPF может подключиться и получить уведомление с помощью кода, меняющего его. Однако, когда вы привязываете сам элемент управления, это не свойство зависимости, и элемент управления не реализует INotifyPropertyChanged, поэтому WPF никогда не узнает, что его свойства изменились.

Я знаю, что могу передать несколько значений в преобразователь с помощью MultiBinding и IMultiValue Converter, но [...]

A MultiBinding позволяет вам выполнять привязку к нескольким свойствам зависимостей и заставлять WPF прослушивать все уведомления об изменении свойств в один раз. Я остановил цитату на «но», потому что неважно, что будет после, это то, что вам нужно сделать.

1 голос
/ 18 июня 2020

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

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

A MultiBinding к обоим ActualWidth или ActualHeight - это путь к go здесь.

Как я могу передать элемент управления, чтобы он обновлялся?

Вы не можете по уже упомянутой причине.

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