Ширина привязки к сумме фактической ширины двух элементов в WPF - PullRequest
0 голосов
/ 27 октября 2018

Я хочу сделать имитацию Datagrid с многоуровневым (2 уровня) заголовком столбца.Я собираюсь определить первый уровень с помощью Grid поверх сетки данных, а вторым уровнем будет сам заголовок сетки данных, как показано ниже:

enter image description here

Проблема Iтеперь (что, вероятно, в valueconventer) заключается в том, что я хочу, чтобы ширина GridColumn1 всегда была суммой ширины 'DataGridColumn1 и DataGridColumn2 столбцов.Для этого я создал преобразователь значений:

public class DataGridExtraHeaderConventer : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            int actualWidth = 0;

            foreach (var item in values)
            {
                actualWidth += System.Convert.ToInt32(item);
            }

            return actualWidth;
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            var x = DependencyProperty.UnsetValue;
            var y = DependencyProperty.UnsetValue;
            return new object[] { x, y };
        }
    }

И определил GridColumn1, как показано ниже:

<Grid.ColumnDefinitions>
                <ColumnDefinition>
                    <ColumnDefinition.Width>
                        <MultiBinding Converter="{StaticResource DataGridExtraHeaderConventer }">
                            <Binding ElementName="Column1" Path="ActualWidth"/>
                            <Binding ElementName="Column2" Path="ActualWidth"/>
                        </MultiBinding>
                    </ColumnDefinition.Width>
                </ColumnDefinition>
                <ColumnDefinition Width="*" />

Datagrid выглядит так:

<DataGrid Name="datagrid1" AutoGenerateColumns="False" Grid.Row="3" RowHeaderWidth="10">
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="Column1" Binding="{Binding something}" Header="column 1" Width="50*" />
                <DataGridTextColumn x:Name="Column2" Binding="{Binding something}"  Header="column 2" Width="60*" />
                <DataGridTextColumn x:Name="Column3" Binding="{Binding something}" Header="column 3" Width="80" />
                <DataGridTextColumn x:Name="Column4" Binding="{Binding something}" Header="column 4" Width="*" />
            </DataGrid.Columns>
        </DataGrid>

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

PS Если я хочу привязать DataGridColumn1 ширину столбца к GridColumn1, это работает:

<ColumnDefinition Width="{Binding ElementName=Column1, Path=ActualWidth}">

1 Ответ

0 голосов
/ 27 октября 2018

Конвертер в вопросе имеет две проблемы:

  1. Значения, передаваемые из свойств ActualWidth в преобразователь, имеют тип double, но преобразователь преобразует их в целочисленные значения. Это приведет к ошибкам округления, в результате чего результат преобразователя будет несколько неточным.

  2. ColumnDefinition.Width относится к типу GridLength. Аргумент targetType метода Convert преобразователя также скажет это. Поскольку целочисленное значение или значение с плавающей запятой неявно / явным образом не преобразуется в GridLength , сам преобразователь должен создать и вернуть такой GridLength объект. В противном случае механизм привязки отклонит результат, полученный преобразователем.

Для решения двух проблем работающий метод Convert может выглядеть, например, так:

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    try
    {
        double sumActualWidths = values.Sum(v => System.Convert.ToDouble(v));
        if (targetType == typeof(GridLength))
            return new GridLength(sumActualWidths);
        else
            return System.Convert.ChangeType(sumActualWidths, targetType);
    }
    catch (Exception ex)
    {
        Oops! Something went wrong.
        I better handle this exception in a meaningful way.

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