Управление (код 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>
Хорошо, вот мой контроль. По сути, я намеревался иметь свойство public зависимости типа bool, которое я мог бы связать с данными (надеюсь). Я решил посмотреть, работает ли он, и поместил его в свой проект вместе с флажком, затем я использовал привязку данных (работает в Blend), чтобы связать Status со свойством IsChecked Checkbox. Я ожидал, чтобы флажок переключал цвет элемента управления.
Обвязка выглядит так:
<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"/>
Кроме того, в окне .Loaded я делаю:
m_indicator.DataContext = this;
Вот мои вопросы:
Что, черт возьми, я сделал не так?
Смогу ли я использовать это в шаблоне ListViewItem? Представление списка будет связано с observable_collection объектов, которые содержат свойство bool (с которым я надеюсь связать.
Что мне нужно сделать, чтобы это заработало?