Silverlight DataStateBehavior、初期値が使用されない
-
22-09-2019 - |
質問
私を利用しようとSilverlight DataStateBehaviorで動作が多いボタンをクリックしを設定するという'選択した物件のモデルはfalseまたはtrueです。のDataStateBehaviorそしてこのVisualStateManagerへの該当状態です。
このように:
<Button...>
<i:Interaction.Behaviors>
<id:DataStateBehavior Binding="{Binding Selected}" Value="True" TrueState="SelectedVisualState" FalseState="DeselectedVisualState"/>
</i:Interaction.Behaviors>
</Button>
以上の作品。思いものがでの設定は正しい状態の場合の申請負荷を組み合わせた設定を選択した物件のビューモデルのデフォルトではtrueでない変化が見られるUIでをクリックしても、ボタンでviewmodel物件です。
ないので複数の授業に関わるDataStateものを含む:
- BindingListener.cs
- ConverterHelper.cs
- DataStateBehavior.cs
- DataStateSwitchBehavior.cs
- DataTrigger.cs
他の手がかりが良いこと 感謝
解決
私は実際に私が試した二答えを追加しようと、それはすべてのXAMLにし、カスタム動作なしで行うことができるので、クリーナーのようですよ。私はちょうど彼らは両方の仕事以来、代替ソリューションのための基準として、他の答えを残しておきます。
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<ic:GoToStateAction StateName="SelectedVisualState"/>
</i:EventTrigger>
</i:Interaction.Triggers>
あなただけのブレンドSDKの一部である組立Microsoft.Expression.Interactionsへの参照を追加で必要になります。
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
他のヒント
DataStateBehaviorクラスのこの拡張機能を試してみてください。ときにターゲット要素のロード、プロパティが更新されたかのようにDataStateBehaviorが評価されます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Gusdor.Wpf
{
/// <summary>
/// Fix for data state behavior. Behavior will trigger transitions when target element loads.
/// </summary>
class DataStateBehaviorFix: Microsoft.Expression.Interactivity.Core.DataStateBehavior
{
public bool UseTransitionsOnLoad { get; set; }
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObject_Loaded;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
Evaluate();
}
void Evaluate()
{
if (Value == null)
{
GotoState(Binding == null, this.AssociatedObject);
}
else GotoState(Value.Equals(Binding), this.AssociatedObject);
}
/// <summary>
/// Attempts to change to the named state. Walks up tree to first match.
/// </summary>
/// <param name="flag"></param>
/// <param name="element"></param>
void GotoState(bool flag, FrameworkElement element)
{
string stateName = flag ? TrueState : FalseState;
if (HasState(element, stateName))
{
bool ret = System.Windows.VisualStateManager.GoToElementState(element, stateName, UseTransitionsOnLoad);
}
else if (element.Parent as FrameworkElement != null)
GotoState(flag, element.Parent as FrameworkElement);
}
/// <summary>
/// Checks if an element has the state named
/// </summary>
/// <param name="element"></param>
/// <param name="stateName"></param>
/// <returns></returns>
bool HasState(FrameworkElement element, string stateName)
{
var groups = Microsoft.Expression.Interactivity.VisualStateUtilities.GetVisualStateGroups(element).Cast<VisualStateGroup>();
return groups.Any(p => p.States.Cast<VisualState>().Any(s => s.Name == stateName));
}
}
}
一つの方法は、あなたがロード時に初期表示状態にそれを置くためにあなたのコントロールに追加することができ振る舞いをすることです。ここでは簡単な例です。
public class InitialVisualStateBehavior : Behavior<Control>
{
public static readonly DependencyProperty InitialStateProperty = DependencyProperty.Register(
"InitialState",
typeof(string),
typeof(InitialVisualStateBehavior),
null);
public string InitialState
{
get { return (string)GetValue(InitialStateProperty); }
set { SetValue(InitialStateProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
if (this.AssociatedObject != null)
{
this.AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
}
}
protected override void OnDetaching()
{
base.OnDetaching();
if (this.AssociatedObject != null)
{
this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
}
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
VisualStateManager.GoToState(this.AssociatedObject, this.InitialState, false);
}
}
あなたはその後、ちょうどXAMLでユーザーコントロールレベルにその振る舞いを追加することになります:
<i:Interaction.Behaviors>
<myi:InitialVisualStateBehavior InitialState="SelectedVisualState" />
</i:Interaction.Behaviors>
また、簡単にカンマを受け入れるために、これを変更する可能性は、あなたがロードした後、別の相互に排他的な状態の束にコントロールを配置するために必要な場合は、その後を通じて分割し、ループ可能性が初期状態のリストを区切ります。
このかもしれないが、また、あなただけのコントロールのLoadedイベントのオフ引き起こす可能性があることTriggerActionにリファクタリングされ、私はきれいになりますどの方法かわからない。