简体   繁体   中英

dependency property in custom control not updating

I'm trying to make a custom control which is basically a TextBox that sits above a datagrid column header and displays the total number in the datagrid column. The control library consists of two custom-controls: DataGridColumnTotal contains the textbox, which also holds references to the DataGrid and ItemsSource. The other is called DataGridHeaderTotalControl, which is basically a style that targets the DataGridColumnHeader. This style places the DataGridColumnTotal control above the existing DatagridColumnHeader and binds the DataGrid and DataGridItemsSource fields from the DataGridColumnTotal control to the Datagrid and ItemsSource fields.

I'm currently just trying to get the TextBox to show if the IsTotalVisible dependency property is set, but it will not update when I try to set it in MainWindow.xaml. I don't have any code in place that displays the total value because I haven't gotten that far yet.

The problem occurs in MainWindow.xaml, when trying to set ctl:DataGridColumnTotal.IsTotalVisible="True" in the dataGridText column. The IsTotalVisible property is not getting set to true. But when I set the default value of the dependency property to true, the total textboxes will show.

DataGridColumnTotal.cs

////////////////////////////////////////////////////////////////////
//DataGridColumnTotal.cs
////////////////////////////////////////////////////////////////////
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Collections;

namespace RiskControlLibrary
{
    public class DataGridColumnTotal : Control
    {
        static DataGridColumnTotal()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridColumnTotal), new FrameworkPropertyMetadata(typeof(DataGridColumnTotal)));
        }

        public static bool GetIsTotalVisible(
            DependencyObject target)
        {
            return (bool)target.GetValue(IsTotalVisibleProperty);
        }

        public static void SetIsTotalVisible(
            DependencyObject target, bool value)
        {
            target.SetValue(IsTotalVisibleProperty, value);
        }

        public static DependencyProperty IsTotalVisibleProperty =
        DependencyProperty.RegisterAttached("IsTotalVisible", typeof(bool), typeof(DataGridColumnTotal), 
        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

    }

    [ValueConversion(typeof(bool), typeof(Visibility))]
    public class BoolToVisibilityConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if ((bool)value)
                return Visibility.Visible;
            else
                return Visibility.Collapsed;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new Exception("Not Implemented.");
        }
    }
}

DataGridHeaderTotalControl.cs

////////////////////////////////////////////////////////////////////
//DataGridHeaderTotalControl.cs
////////////////////////////////////////////////////////////////////
using System.Windows;
using System.Windows.Controls;

namespace RiskControlLibrary
{
    public class DataGridHeaderTotalControl : Control
    {
        static DataGridHeaderTotalControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(DataGridHeaderTotalControl), new FrameworkPropertyMetadata(typeof(DataGridHeaderTotalControl)));
        }
    }
}

Generic.xaml

////////////////////////////////////////////////////////////////////
//Generic.xaml
////////////////////////////////////////////////////////////////////
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:RiskControlLibrary"
    xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    xmlns:s="clr-namespace:System;assembly=mscorlib">

    <Style TargetType="{x:Type local:DataGridColumnTotal}">
        <Style.Resources>
            <local:BoolToVisibilityConverter x:Key="booleanToVisibilityConverter" />
        </Style.Resources>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type local:DataGridColumnTotal}">
                    <Border Background="{TemplateBinding Background}"
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <TextBox
                            x:Name="PART_TextBoxTotal"
                            IsReadOnly="True"
                            VerticalAlignment="Top"
                            VerticalContentAlignment="Center"
                            Text="{Binding Total,
                                RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:DataGridColumnTotal}}}"
                            Visibility="{Binding IsTotalVisible, RelativeSource={RelativeSource TemplatedParent},
                            Converter={StaticResource booleanToVisibilityConverter}}"
                         >
                        </TextBox>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style TargetType="{x:Type DataGridColumnHeader}"
           x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:DataGridHeaderTotalControl},
           ResourceId=DataGridHeaderTotalControlStyle}">
        <Setter Property="Template">

            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridColumnHeader}">

                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition />
                        </Grid.ColumnDefinitions>
                        <Grid.RowDefinitions>
                            <RowDefinition />
                            <RowDefinition />
                        </Grid.RowDefinitions>

                        <local:DataGridColumnTotal Margin="1" Grid.Column="0" Grid.Row="0"/>

                            <theme:DataGridHeaderBorder Grid.Column="0" Grid.Row="1" SortDirection="{TemplateBinding SortDirection}"
                                     IsHovered="{TemplateBinding IsMouseOver}"
                                     IsPressed="{TemplateBinding IsPressed}"
                                     IsClickable="{TemplateBinding CanUserSort}"
                                     Background="{TemplateBinding Background}"
                                     BorderBrush="{TemplateBinding BorderBrush}"
                                     BorderThickness="{TemplateBinding BorderThickness}"
                                     Padding ="{TemplateBinding Padding}"
                                     SeparatorVisibility="{TemplateBinding SeparatorVisibility}"
                                     SeparatorBrush="{TemplateBinding SeparatorBrush}">

                            <TextBlock Grid.Column="0" Grid.Row="1"  Text="{TemplateBinding  Content}" 
                                  SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                  VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                       TextWrapping="Wrap"></TextBlock>

                        </theme:DataGridHeaderBorder>

                    </Grid>

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

MainWindow.xaml

////////////////////////////////////////////////////////////////////
//MainWindow.xaml
////////////////////////////////////////////////////////////////////
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:app="clr-namespace:WpfApplication1"
        xmlns:ctl="clr-namespace:RiskControlLibrary;assembly=RiskControlLibrary"
        Title="MainWindow" Height="341" Width="452"
        Loaded="Window_Loaded">
    <Grid>
        <DataGrid 
            Name="m_dgOrder"
            ItemsSource="{Binding ListPos}"
            GridLinesVisibility="None"
            AutoGenerateColumns="False"
            IsReadOnly="True"
            Background="White"
            CanUserResizeRows="False"
            HeadersVisibility="Column"
            RowHeaderWidth="0"
            ColumnHeaderStyle="{StaticResource {ComponentResourceKey 
            TypeInTargetAssembly={x:Type ctl:DataGridHeaderTotalControl}, 
            ResourceId=DataGridHeaderTotalControlStyle}}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Symbol" Binding="{Binding Path=Symbol}"/>
                <DataGridTextColumn Header="Pos" Binding="{Binding Path=Pos}" ctl:DataGridColumnTotal.IsTotalVisible="True"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

I was registering the IsTotalVisible property to the wrong class. Instead of DataGridColumnTotal it should've been DataGridTextColumn.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM