问题
Question: How do I bind StatName.Width
to Samp1.ActualWidth + Samp2.ActualWidth
?
Sub-questions:
Why are my WidthConverter
functions never executed (breakpoints never hit)?
What is the right <Binding ...
syntax for the individual MultiBinding components?
What I've tried:
I think I need to assign the DataGridTextColumn.Width
with MultiBinding
and some type of converter.
I have tried putting together a solution from various examples online. I can't seem to pull it all together.
EDIT
With using <Binding ElementName="Samp1" Path="ActualWidth" />
- No build errors or warnings.
- The
Convert
function is not hit - No relevant messages in Output
With using <Binding Source="{x:Reference Samp1}" Path="ActualWidth" />
- Build error (that still allows execution): Specified cast is not valid. For
<MultiBinding>...</MultiBinding>
. Convert
is called three times when loading. It is not called when resizing columnSamp1
.- On each execution of
Convert:
System.Windows.Data Error: 5 : Value produced by BindingExpression is not valid for target property.; Value='40' MultiBindingExpression:target element is 'DataGridTextColumn' (HashCode=64879470); target property is 'Width' (type 'DataGridLength')
MultiBinding Attempt (xaml part)
<Page.Resources>
<local:WidthConverter x:Key="WidthConverter" />
</Page.Resources>
<StackPanel>
<DataGrid IsReadOnly="True" HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn x:Name="Samp1" Binding="{Binding a}" Header="S1" />
<DataGridTextColumn x:Name="Samp2" Binding="{Binding b}" Header="S2" />
<DataGridTextColumn x:Name="Total" Binding="{Binding c}" Header="Tot" />
</DataGrid.Columns>
<local:MyGenericRecord a="5000" b="2500" c="7500" />
<local:MyGenericRecord a="1000" b="1500" c="2500" />
</DataGrid>
<DataGrid IsReadOnly="True" HeadersVisibility="Column">
<DataGrid.Columns>
<DataGridTextColumn x:Name="StatName" Binding="{Binding a}" Header="Stat">
<DataGridTextColumn.Width>
<MultiBinding Converter="{StaticResource WidthConverter}">
<Binding ElementName="Samp1" Path="ActualWidth" />
<Binding ElementName="Samp2" Path="ActualWidth" />
</MultiBinding>
</DataGridTextColumn.Width>
</DataGridTextColumn>
<DataGridTextColumn x:Name="StatValue" Binding="{Binding b}" Header="Val" Width="{Binding ElementName=Total, Path=ActualWidth}" />
</DataGrid.Columns>
<local:MyGenericRecord a="Min" b="2500" />
<local:MyGenericRecord a="Max" b="7500" />
<local:MyGenericRecord a="Average" b="5000" />
</DataGrid>
</StackPanel>
MultiBinding Attempt (code part)
public class WidthConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double totalWidth = 0;
foreach (DataGridLength Width in values)
totalWidth += Width.Value;
return totalWidth;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
回答1:
The code finally executes as expected with the following:
<Binding Source="{x:Reference Samp2}" Path="ActualWidth" />
return new DataGridLength(totalWidth);
The Converter
gets called on load and when resizing Samp1
or Samp2
. The column widths remain synchronized as expected.
<DataGridTextColumn x:Name="StatName" Binding="{Binding a}" Header="Stat">
<DataGridTextColumn.Width >
<MultiBinding Converter="{StaticResource WidthConverter}">
<Binding Source="{x:Reference Samp1}" Path="ActualWidth" />
<Binding Source="{x:Reference Samp2}" Path="ActualWidth" />
</MultiBinding>
</DataGridTextColumn.Width>
</DataGridTextColumn>
The Convert
function needed to return a DataGridLength
, the data type of DataGridTextColumn.Width
.
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double totalWidth = 0;
foreach (double Width in values)
totalWidth += Width;
return new DataGridLength(totalWidth);
}
Note: The code executes as expected, regardless of the error Specified cast is not valid.
- The Visual Studio designer underlines the entire tag
<MultiBinding ... </MultiBinding>
in cyan. - The Error List window reports the error "Specified cast is not valid."
- While it is displayed as an error, Visual Studio will still build and execute the code.
来源:https://stackoverflow.com/questions/47762162/bind-datagrid-column-width-to-two-colums-of-another-datagrid