代码之家  ›  专栏  ›  技术社区  ›  Maciek

自定义指示器控件

  •  1
  • Maciek  · 技术社区  · 15 年前

    控制(C代码):

    public partial class RedGreenStatusIndicator : UserControl, INotifyPropertyChanged
    {
        public RedGreenStatusIndicator()
        {
            this.InitializeComponent();
    
            DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty
                (ArchiverDetails.ArDetailsProperty,
                typeof(ArchiverDetails));
    
            dpd.AddValueChanged(this, delegate { this.ObjectValueChanged(); });
            Status = false;
        }
    
        void RedGreenStatusIndicator_Loaded(object sender, RoutedEventArgs e)
        {
    
        }
    
        public bool Status
        {
            get { return (bool)GetValue(StatusProperty); }
            set 
            {
                bool old_value = Status;
                SetValue(StatusProperty, value);
    
                if ((old_value == true) && (Status == false))
                {
                    hide_green();
                    show_red();
                }
    
                if((old_value == false) && (Status == true))
                {
                    hide_red();
                    show_green();
                }
            }
        }
    
        private void show_green()
        {
            if (GreenInterior.Opacity == 0)
                run_storyboard("show_green_indicator");
        }
    
        private void hide_green()
        {
            if (GreenInterior.Opacity != 0)
                run_storyboard("hide_green_indicator");
        }
    
        private void show_red()
        {
            if (RedInterior.Opacity == 0)
                run_storyboard("show_red_indicator");
        }
    
        private void hide_red()
        {
            if (RedInterior.Opacity != 0)
                run_storyboard("hide_red_indicator");
        }
    
        private void run_storyboard(string resource_name)
        {
            Storyboard sb = (Storyboard)FindResource(resource_name);
            sb.Begin();
        }
    
        public static readonly DependencyProperty StatusProperty =
            DependencyProperty.Register("Status",
            typeof(bool),
            typeof(RedGreenStatusIndicator),
            new PropertyMetadata(null));
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        private void ObjectValueChanged()
        {
            OnPropertyChanged("Status");
        }
    
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        #endregion
    }
    

    XAML:

    <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 mc:Ignorable="d"
                 x:Class="Manager.RedGreenStatusIndicator"
                 x:Name="UserControl"
                 d:DesignWidth="640" d:DesignHeight="480">
        <UserControl.Resources>
            <Storyboard x:Key="show_green_indicator">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenInterior" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="hide_green_indicator">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="GreenInterior" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="show_red_indicator">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RedInterior" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
            <Storyboard x:Key="hide_red_indicator">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="RedInterior" Storyboard.TargetProperty="(UIElement.Opacity)">
                    <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </UserControl.Resources>
        <Border BorderBrush="{DynamicResource SPDC_GRAY}" Background="{DynamicResource SPDC_BLACK}" CornerRadius="5,5,5,5" BorderThickness="1,1,1,1">
            <Grid Margin="2,2,2,2">
                <Grid.RowDefinitions>
                    <RowDefinition Height="0.5*"/>
                    <RowDefinition Height="0.5*"/>
                </Grid.RowDefinitions>
                <Border HorizontalAlignment="Stretch" x:Name="RedInterior" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Grid.RowSpan="2" Background="#FFF21818" Opacity="0"/>
                <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Height="Auto" Grid.RowSpan="2" x:Name="GreenInterior" Background="#FF1DD286" Opacity="0"/>
                <Border Margin="0,0,0,0" x:Name="Reflection" CornerRadius="5,5,0,0">
                    <Border.Background>
                        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                            <GradientStop Color="#99FFFFFF" Offset="0"/>
                            <GradientStop Color="#33FFFFFF" Offset="1"/>
                        </LinearGradientBrush>
                    </Border.Background>
                </Border>
            </Grid>
        </Border>
    </UserControl>
    

    好吧,这是我的控制。基本上,我希望它具有bool类型的公共依赖属性,我可以将其数据绑定到(希望如此)。我决定看看它是否有效,并将其与复选框一起放入我的项目中,然后使用数据绑定(在Blend中工作)将状态绑定到复选框的IsChecked属性。我本来想让复选框切换控件的颜色。

    绑定如下:

    <RedGreenStatusIndicator HorizontalAlignment="Left" Margin="100,146,0,0" VerticalAlignment="Top" Width="64" Height="64" Status="{Binding Path=IsChecked, ElementName=checkBox, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="m_indicator"/>
            <CheckBox Margin="212,168,315,0" VerticalAlignment="Top" Height="24" Content="Click Me!" Style="{DynamicResource GlassCheckBox}" Foreground="{DynamicResource SPDC_WHITE}" x:Name="checkBox"/>
    

    另外,在窗户里,我正在做:

    m_indicator.DataContext = this;
    

    以下是我的问题:

    我到底做错了什么? 我可以在ListViewItem模板中使用它吗?ListView将被数据绑定到包含bool属性(我希望绑定到该属性)的可观察对象集合。

    我需要做什么才能让它工作?

    1 回复  |  直到 8 年前
        1
  •  4
  •   Matthias    15 年前

    尽量把代码放在后面。
    尤其是:不要将任何内容放入依赖属性“access property”setter中-当wpf更改值时,不会执行此代码。

    试试这个:
    代码落后:

    public partial class StatusIndicator 
        : UserControl
    {
        public static readonly DependencyProperty IsGreenProperty = DependencyProperty.Register("IsGreen", typeof(bool), typeof(StatusIndicator), new UIPropertyMetadata(false));
    
        public bool IsGreen
        {
            get
            {
                return (bool) GetValue(IsGreenProperty);
            }
            set
            {
                SetValue(IsGreenProperty, value);
            }
        }
    
    
        public StatusIndicator()
        {
            InitializeComponent();
        }
    }
    

    XAML:

    <UserControl x:Class="WpfApplication1.StatusIndicator"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:WpfApplication1="clr-namespace:WpfApplication1"
        Height="300" Width="300" x:Name="this">
        <UserControl.Template>
            <ControlTemplate TargetType="{x:Type WpfApplication1:StatusIndicator}">
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding ElementName=this, Path=IsGreen}"
                                 Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard FillBehavior="HoldEnd">
                                    <DoubleAnimation Duration="0:0:0.500"
                                                     From="0"
                                                     To="1"
                                                     Storyboard.TargetName="green"
                                                     Storyboard.TargetProperty="Opacity" />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
    
                        <DataTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation Duration="0:0:0.500"
                                                     From="1"
                                                     To="0"
                                                     Storyboard.TargetName="green"
                                                     Storyboard.TargetProperty="Opacity" />
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </ControlTemplate.Triggers>
    
                <Grid>
                    <Rectangle x:Name="red"
                               Fill="Red"/>
                    <Rectangle x:Name="green"
                               Fill="Green" 
                               Opacity="0" />
                </Grid>
            </ControlTemplate>
        </UserControl.Template>
    </UserControl>