问题
I have developed a custom data grid control. This control has two parts, one is the custom template used by the data grid itself and the other is my custom control which adds a title area to the data grid.
I have a class called CustomDataGrid, here is the XAML.
<UserControl x:Class="MDT_Designer.Presentation.ScreenControls.CustomDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Name="CDataGrid" >
<UserControl.Resources>
<ResourceDictionary x:Key="Dictionary" Source="CustomizedControls.xaml"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=CDataGrid, Path=TitleAreaHeight}"/>
<RowDefinition Height="{Binding ElementName=CDataGrid, Path=GridAreaHeight}"/>
</Grid.RowDefinitions>
<Grid Name="TitleArea" DockPanel.Dock="Top" Background="{Binding ElementName=CDataGrid, Path=TitleBackColor}" >
<Viewbox HorizontalAlignment="{Binding ElementName=CDataGrid, Path=TitleAlignment}">
<TextBlock Name="TitleText" Text="{Binding ElementName=CDataGrid, Path=Title}" Margin="2,0,0,0" FontFamily="{Binding ElementName=CDataGrid, Path=TitleFontFamily}" Foreground="{Binding ElementName=CDataGrid, Path=TitleTextColor}"/>
</Viewbox>
</Grid>
<DataGrid Name="DataGridArea" Grid.Row="1" IsReadOnly="True" HorizontalGridLinesBrush="DarkGray" VerticalGridLinesBrush="DarkGray" VerticalScrollBarVisibility="Visible" Background="AliceBlue" >
</DataGrid>
</Grid>
</UserControl>
In my CustomDataGrid.xaml.cs file I have defined properties as such.
public static DependencyProperty TitleAlignmentProperty = DependencyProperty.Register("TitleAlignment", typeof(HorizontalAlignment), typeof(CustomDataGrid));
public HorizontalAlignment TitleAlignment
{
get { return (HorizontalAlignment)base.GetValue(TitleAlignmentProperty); }
set { base.SetValue(TitleAlignmentProperty, value); }
}
I am just showing one as a sample, and this works. I do wish that I could change the binding in the XAML to get rid of ElementName=CDataGrid, but any way I have as an alternative doesn't work.
Now to my problem. My custom template for the data grid control itself is stored in the dictionary CustomizedControls.xaml.
Here is one example of binding issues. I had to create this resource.
<LinearGradientBrush x:Key="HeaderBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0" >
<GradientStop Color="{DynamicResource {x:Static SystemColors.ControlLightColorKey}}" Offset="0" />
<GradientStop Color="{DynamicResource {x:Static SystemColors.ControlDarkColorKey}}" Offset="1" />
</LinearGradientBrush>
Then I use it in Border definition for the column header.
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border x:Name="columnHeaderBorder" BorderThickness="1" Padding="3,0,3,0"
Background="{DynamicResource HeaderBackgroundBrush}">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<ContentPresenter x:Name="columnHeaderPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{DynamicResource HeaderContentStyle}" />
</Border>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then to change it in my code behind I have to do this.
LinearGradientBrush headerBrush = (LinearGradientBrush)TryFindResource("HeaderBackgroundBrush");
headerBrush.GradientStops[0] = new GradientStop(brush.Color, 0.0);
I cannot change the brush itself, I can just change a property of the brush. I have tried every binding technique I can think of, but nothing seems to work when the style is in a dictionary.
What I would like to be able to do is somehow bind something like BorderLightColor, which is BorderBrush setting, so that in my code behind I can change it's value.
Any help would make my day, it would make my whole weekend in fact. Thanks.
回答1:
Why cant you change the brush? You should be able to just assign the brush reference to the control. Does this not work? FindResource should search the Parent Element of the FrameworkElement you are calling it on and up the tree, the application resources, then Themes ending in System Resources. Forgive my VB...
Private Sub Button_Click(ByVal sender as Object, ByVal e as System.Windows.RoutedEventArgs)
Dim MyBrush2 as Brush = Me.FindResource("Brush2")
Me.MyRect.Background = MyBrush2
End Sub
And the window contents:
<Window.Resources>
<LinearGradientBrush x:Key="Brush1" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Brush2" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0800FF" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid x:Name="MyRect" HorizontalAlignment="Left" Margin="63,66,0,174" Width="242" Background="{DynamicResource Brush1}" />
<Button Content="Button" HorizontalAlignment="Right" Height="60" Margin="0,117,95,0" VerticalAlignment="Top" Width="156" Click="Button_Click"/>
</Grid>
来源:https://stackoverflow.com/questions/6794703/wpf-binding-issues-with-resource-dictionaries