1

WPFコントロールの 2つの視覚状態を作成するにはどうすればよいですか。境界の背景色を元に戻して点滅を停止する1 つの法線はありますか?BorderTransparentRedTransparent

注: WPFコントロールは、別のコントロールのBorder内部で使用されます。ContentTemplate

また、一部のプロパティが からへIsEnabledの変更、およびその逆の変更について言うときに、それらをトリガーする必要があります。IsEnabled プロパティは ViewModel プロパティにバインドされています。境界線をクリックすると、点滅が停止し、背景が通常の状態に戻ります。BorderFalseTrue

4

2 に答える 2

3

VisualStateManager を使用して VisualStates を定義できます。Border で必要な動作を取得するには、次のことを出発点として使用することをお勧めします。

xaml:

  <Border Name="TheBorder" BorderThickness="5"
            Margin="30" Padding="20"
            wpfApplication1:StateManager.VisualState="{Binding ElementName=TheBorder,
                                                               Path=IsEnabled, Mode=TwoWay,
                                                               Converter={StaticResource EnabledToVisualStateConverter}}">
        <Border.Background>
            <SolidColorBrush x:Name="BackgroundBrush" Color="Transparent"/>
        </Border.Background>
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup Name="Common">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="Flash">
                    <Storyboard>
                        <ColorAnimation Storyboard.TargetName="BackgroundBrush" 
                                        Storyboard.TargetProperty="Color" To="Red"
                                        RepeatBehavior="Forever"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </Border>

コンバーター:

    public class EnabledToVisualStateConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var isEnabled = (bool) value;
        if (isEnabled)
            return "Flash";

        return "Normal";
    }

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

VisualState を変更するために使用される StateManager クラス:

    public class StateManager
{
    private static string _valueToApplyOnInitialization;

    public static readonly DependencyProperty VisualStateProperty =
        DependencyProperty.RegisterAttached("VisualState", typeof (string), typeof (StateManager),
                                            new PropertyMetadata(VisualStateChangeCallback));

    public static string GetVisualState(DependencyObject obj)
    {
        return (string)obj.GetValue(VisualStateProperty);
    }
    public static void SetVisualState(DependencyObject obj, string value)
    {
        obj.SetValue(VisualStateProperty, value);
    }

    public static void VisualStateChangeCallback(object sender, DependencyPropertyChangedEventArgs args)
    {
        var element = sender as FrameworkElement;
        if (element == null)
            return;

        if (!element.IsInitialized)
        {
            _valueToApplyOnInitialization = (String) args.NewValue;
            element.Initialized += OnElementInitialized;
        }
        else
            VisualStateManager.GoToElementState(element, (string)args.NewValue, true);
    }

    private static void OnElementInitialized(object sender, EventArgs e)
    {
        var element = sender as FrameworkElement;
        if (element == null)
            return;

        VisualStateManager.GoToElementState(element, _valueToApplyOnInitialization, true);
        element.Initialized -= OnElementInitialized;
    }
}

Border の IsEnabled プロパティではなく、ViewModel のプロパティを使用する場合は、Binding to 'TheBorder' を ViewModel プロパティに置き換えます。

于 2013-06-04T20:36:08.367 に答える