WPF中树视图项中子控件的绑定

时间:2016-04-23 12:59:21

标签: wpf treeviewitem

我有一个使用HierarchicalDataTemplate创建的树视图,并使用自定义类进行绑定。在treeview子项中,我有复选框,文本块和图像。我想要的是每当在UI上手动检查复选框时,我希望我的图像更改为正确的符号。 我无法弄清楚我该怎么做。以下是XAML。

<UserControl x:Class="Repayment.TreeViewCustom"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<UserControl.Resources>
    <SolidColorBrush x:Key="SolidColorBrush1" />
    <SolidColorBrush x:Key="SolidColorBrush2" />
    <SolidColorBrush x:Key="SolidColorBrush3" />
    <SolidColorBrush x:Key="SolidColorBrush4" />
    <SolidColorBrush x:Key="SolidColorBrush5" />
    <SolidColorBrush x:Key="SolidColorBrush6" />

    <Style TargetType="TextBlock" x:Key="HeaderTextBlock">
        <Setter Property="Foreground" Value="{DynamicResource SolidColorBrush4}"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Margin" Value="10 5 10 5"/>
        <Setter Property="FontFamily" Value="Century Gothic"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="FontStyle" Value="Italic"/>
    </Style>

    <Style TargetType="TextBlock" x:Key="ChildTextBlock">
        <Setter Property="Foreground" Value="{DynamicResource SolidColorBrush3}"/>
        <Setter Property="FontSize" Value="14"/>
        <Setter Property="Margin" Value="10 5 10 5"/>
        <Setter Property="FontFamily" Value="Century Gothic"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="FontStyle" Value="Italic"/>
    </Style>
    <Style TargetType="TreeView" x:Key="BackgroundTreeView">
        <Setter Property="Background" Value="{DynamicResource SolidColorBrush1}"/>
    </Style>

    <Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBox}">
        <Setter Property="SnapsToDevicePixels" Value="true" />
        <Setter Property="OverridesDefaultStyle" Value="true" />
        <Setter Property="Height" Value="30" />
        <Setter Property="FocusVisualStyle" Value="{DynamicResource MyFocusVisualStyte}" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <BulletDecorator>
                        <BulletDecorator.Bullet>
                            <Grid Height="{TemplateBinding Height}" Width="{Binding RelativeSource={RelativeSource Self}, Path=Height, UpdateSourceTrigger=PropertyChanged}"
                          MinHeight="30" MinWidth="30" ShowGridLines="False">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="4*" />
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="4*" />
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="1*" />
                                    <ColumnDefinition Width="2*" />
                                    <ColumnDefinition Width="2*" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="3*" />
                                    <RowDefinition Height="1*" />
                                    <RowDefinition Height="1*" />
                                    <RowDefinition Height="1*" />
                                    <RowDefinition Height="4*" />
                                    <RowDefinition Height="1*" />
                                    <RowDefinition Height="1*" />
                                    <RowDefinition Height="4*" />
                                </Grid.RowDefinitions>

                                <Border Name="MainBorder"
                                Grid.ColumnSpan="9" Grid.RowSpan="9"
                                CornerRadius="4"
                                BorderThickness="1"
                                Background="Transparent" />
                                <!--Transparent-->

                                <Border Name="InnerBorder"
                                Grid.Column="1" Grid.ColumnSpan="5"
                                Grid.Row="2" Grid.RowSpan="5"
                                BorderThickness="1"
                                BorderBrush="#808080" />
                                <!--#808080-->

                                <Path Name="InnerPath"
                              Grid.Column="1" Grid.ColumnSpan="5"
                              Grid.Row="2" Grid.RowSpan="5"
                              Data="M31,5 L19.5,5 19.5,19.5 34.5,19.5 34.5,11.75"
                              Stretch="Fill" Stroke="#808080"/>

                                <Path Name="CheckMark"
                              Grid.Column="2" Grid.ColumnSpan="5"
                              Grid.Row="1" Grid.RowSpan="5"
                              Opacity="0"
                              Data="M9.07743946676476E-09,4.31805768640244L4.68740335877841,8.86361158398516C4.68740335877841,8.86361158398516,16.3281249985376,-2.42451336648723,16.3281249985376,-2.42451336648723L14.0622100581796,-4.77304938341948 4.68740335877846,4.31805791992662 2.22656251699567,1.93164208562579z"
                              Fill="#3babe3" 
                              Stretch="Fill"
                              Stroke="#3babe3" />

                                <Path Name="InderminateMark"
                              Grid.Column="3"
                              Grid.Row="4"
                              Data="M0,4 L1,5 5,1 4,0"
                              Opacity="0"
                              Stretch="Fill"
                              StrokeThickness="0"
                              Fill="#808080" />
                            </Grid>
                        </BulletDecorator.Bullet>
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CheckStates">
                                <VisualState x:Name="Checked">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                         Storyboard.TargetName="CheckMark" Duration="0:0:0.1" To="1" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Unchecked" >
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                         Storyboard.TargetName="CheckMark" Duration="0:0:0.2" To="0" />
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Indeterminate">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetProperty="Opacity"
                                         Storyboard.TargetName="InderminateMark" Duration="0:0:0.1" To="1" />
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter Margin="4,0,4,0"
                    VerticalAlignment="Center"
                    HorizontalAlignment="Left"
                    RecognizesAccessKey="True" />
                    </BulletDecorator>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="True">
                            <Setter TargetName="InnerBorder" Property="Visibility" Value="Collapsed" />
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="MainBorder" Property="Background" Value="#81d2eb" />
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="CheckMark" Property="Fill" Value="#cccccc" />
                            <Setter TargetName="CheckMark" Property="Stroke" Value="#cccccc" />
                            <Setter TargetName="InnerPath" Property="Stroke" Value="#cccccc" />
                            <Setter TargetName="InderminateMark" Property="Fill" Value="#cccccc" />
                            <Setter TargetName="InnerBorder" Property="BorderBrush" Value="#cccccc" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <TreeView MinWidth="200" Name ="tvMain" TreeViewItem.Selected="tvMain_Selected" Style="{DynamicResource BackgroundTreeView}">
        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="IsExpanded" Value="True"/>
            </Style>
        </TreeView.ItemContainerStyle>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate  ItemsSource="{Binding ChildStep}">
                <Border MinWidth="270" Height="26" Background="{DynamicResource SolidColorBrush2}" BorderBrush="{DynamicResource SolidColorBrush1}" BorderThickness="1" CornerRadius="2" Margin="2" Padding="2">
                    <StackPanel Orientation="Horizontal" >
                        <TextBlock  Text="{Binding Name}" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{DynamicResource HeaderTextBlock}"></TextBlock>
                    </StackPanel>
                </Border>
                <HierarchicalDataTemplate.ItemTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding GrandChildStep}">
                        <Border Width="250"  Background="{DynamicResource SolidColorBrush1}" BorderBrush="{DynamicResource SolidColorBrush2}"  CornerRadius="2" Margin="1" >
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="26"></ColumnDefinition>
                                    <ColumnDefinition Width="*"></ColumnDefinition>
                                    <ColumnDefinition Width="26"></ColumnDefinition>
                                </Grid.ColumnDefinitions>

                                <CheckBox Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" IsChecked="{Binding Path=IsCheckBoxChecked}" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{DynamicResource CheckBoxStyle}" Grid.Column="0" />
                                <TextBlock Grid.Column="1" Margin="2"  Text="{Binding Path=Name}" Style="{DynamicResource ChildTextBlock}"  VerticalAlignment="Center"></TextBlock>

                                <!--<Rectangle Name ="rct" Width="20" Fill="{Binding Path=Color}" Grid.Column="1" HorizontalAlignment="Right" Margin="2"></Rectangle>-->
                                <Image Grid.Column="2" Source="{Binding ImageUrl}" HorizontalAlignment="Right" Margin="2"></Image>

                            </Grid>
                        </Border>
                        <HierarchicalDataTemplate.ItemTemplate>
                            <DataTemplate>
                                <Border Width="200"  Background="LightBlue" CornerRadius="2" Margin="1" >
                                    <Grid>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*"></ColumnDefinition>
                                            <ColumnDefinition Width="26"></ColumnDefinition>
                                        </Grid.ColumnDefinitions>

                                        <TextBlock Margin="2"  Text="{Binding Path=Name}" FontWeight="Bold" VerticalAlignment="Center"></TextBlock>
                                        <Rectangle Width="20" Fill="DarkOrchid" Grid.Column="1" HorizontalAlignment="Right" Margin="2"></Rectangle>

                                    </Grid>
                                </Border>
                            </DataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>
                    </HierarchicalDataTemplate>
                </HierarchicalDataTemplate.ItemTemplate>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
</Grid>

1 个答案:

答案 0 :(得分:0)

您可以使用多绑定转换器来获取对象集合并根据这些对象返回值。这是一个例子;

 public class CheckedAndImageURLMultiValueConverter : IMultiValueConverter
 {
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var checkboxIsChecked = (bool?)values[0];

        ImageSource newImageURL = ...;

        var imageURL = (ImageSource)values[1];

        if (checkboxIsChecked == true)
        {
            return newImageURL;
        }
        return imageURL;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在这个示例中,如果选中复选框,则会获得一个图像源,如果没有,则会获得另一个图像源,这可能不是您想要的(并且我没有包含newImageSource的值)但希望您能够根据您的需求进行调整。

接下来,您需要在xaml中添加对它的引用。像这样的东西;

    <Window.Resources>
        ...
        <local:CheckedAndImageURLMultiValueConverter x:Key="AndImageUrlMultiValueConverter"/>
    </Window.Resources>

最后你必须更换你的图像xaml以使用类似这样的多重绑定;

            <Image Grid.Column="2" HorizontalAlignment="Right" Margin="2">
            <Image.Source>
                <MultiBinding Converter="{StaticResource AndImageUrlMultiValueConverter}">
                    <Binding Path="IsCheckBoxChecked" />
                    <Binding Path="ImageURL" />
                </MultiBinding>
            </Image.Source>
        </Image>

由于您正在使用转换器,因此您可以非常灵活地使用绑定的内容,只需将对象值关闭回multiConverter中的原始类型,执行您需要的逻辑,然后根据此返回值。 / p>

注意绑定在xaml中出现的顺序,它们需要匹配multiConverter中object []值的顺序。

你不必仅限于两个绑定。多转换器允许您绑定更多。

我希望这会有所帮助。