UPDATE:
Download a small test app here
I have a custom control consisting of a border, button and textblock. When the control is pressed I display a popup picker control. I'm having a problem using visual state to properly enable and disable the control.
When I enable and disable the control normally using the Normal and Disabled visual state it works fine:
Enabled:
Disabled:
If I click the control then disable the control the background stays white:
Any ideas?
UPDATE: I think that I am missing a property in my visual state that is getting set by the system. I'm hoping someone can identify what it is so I can override it.
Here is the style:
<Style
TargetType="Controls:PickerBoxButton">
<Setter
Property="Background"
Value="Transparent" />
<Setter
Property="BorderBrush"
Value="{StaticResource PhoneForegroundBrush}" />
<Setter
Property="Foreground"
Value="{StaticResource PhoneForegroundBrush}" />
<Setter
Property="BorderThickness"
Value="{StaticResource PhoneBorderThickness}" />
<Setter
Property="FontFamily"
Value="{StaticResource PhoneFontFamilyNormal}" />
<Setter
Property="FontSize"
Value="{StaticResource PhoneFontSizeMediumLarge}" />
<Setter
Property="Padding"
Value="8,3,8,5" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="Controls:PickerBoxButton">
<Grid
Background="Transparent">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup
x:Name="CommonStates">
<VisualState
x:Name="Normal">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneForegroundBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PickerButton"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneTextBoxBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PickerText"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneTextBoxForegroundBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState
开发者_开发技巧 x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="ButtonBackground"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PickerButton"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneChromeBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Storyboard.TargetName="PickerText"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame
KeyTime="0"
Value="{StaticResource PhoneDisabledBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border
x:Name="ButtonBackground"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="0"
Background="{TemplateBinding Background}"
Margin="6,8,8,0"
>
<Button
x:Name="PickerButton"
BorderThickness="0"
Height="64"
HorizontalAlignment="Left"
Margin="-12,-12,0,-12"
VerticalAlignment="Top"
Width="700">
<StackPanel
Orientation="Horizontal"
Width="700">
<TextBlock
x:Name="PickerText"
Margin="-2, 0, 0, 0"
/>
</StackPanel>
</Button>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
UPDATE
Added code from control showing visual state change trigger.
private bool _isReadOnly;
public bool IsReadOnly
{
get { return _isReadOnly; }
set
{
_isReadOnly = value;
UpdateVisualState();
}
}
private void UpdateVisualState()
{
VisualStateManager.GoToState(this, IsReadOnly ? "Disabled" : "Normal", false);
}
From your description, you are setting IsReadOnly to true but this won't make the control go to the Disabled state. You should set IsEnabled to False instead. Can you please give it a try?
Wonder if this would work... In your PickerBoxButton's constructor, do
this.IsEnabledChanged += (s, e) =>
{
if ((bool)e.NewValue)
VisualStateManager.GoToState((PickerBoxButton)s, "Disabled", true);
};
and in wherever you set your IsReadOnly property, replace it with
this.YourCustomControl.IsEnabled = false;
With your sample project, I found when animating a rectangle instead of button and textblock it actually worked as expected. Then I suspected this might because GoToState triggers the underlying controls' visual states to change as they share the same visual states names. I then changed your visual states names from 'Normal' to 'NormalState', 'Disabled' to 'Disabled', then everything worked. :)
Also please remove the code I gave to you, and use your original IsReadOnly property to trigger the state change.
精彩评论