データナビゲータとして使用するUserControlを作成しました。次のように私は(DependencyPropertyには暗黙の)このコントロールで2 DependencyPropertiesを定義した:WPF UserControlでボタンの有効状態を動的に変更するための条件付きデータトリガー
public ICollection DataCollection
{
get { return GetValue(DataCollectionProperty) as ICollection; }
set { SetValue(DataCollectionProperty, value); }
}
public ICollectionView View
{
get { return (DataCollection == null ? null : CollectionViewSource.GetDefaultView(DataCollection)); }
}
はその後、私は基本的なナビゲーション操作を実行するために4つのボタンを入れてきました(最初、前、次、最後)。各ボタンには、次のスタイルを取得します。
<Style x:Key="NavButtonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<DataTrigger Binding="{Binding DataCollection}" Value="{x:Null}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Style.Triggers>
</Style>
すべてこのトリガーDataCollectionたDependencyPropertyがnullの場合、このように、RelativeResource TemplatedParentは、各ボタンのDataContextのとして渡されると仮定し、チェックするためにされない:
<Button (...) DataContext="{RelativeSource TemplatedParent}">
は、その後、私は比較演算と比較した値に基づき、値を比較し、trueまたはfalseを返すために、次のMarkupExtensionを作成:
[MarkupExtensionReturnType(typeof(bool))]
public class ComparisonBinding : BindingDecoratorBase
{
public ComparisonOperation Operation { get; set; }
public object Comparand { get; set; }
public override object ProvideValue(IServiceProvider provider)
{
base.ProvideValue(provider);
DependencyObject targetObject;
DependencyProperty targetProperty;
bool status = TryGetTargetItems(provider, out targetObject, out targetProperty);
if (status && Comparand != null)
{
if (Comparand is MarkupExtension)
Comparand = (Comparand as MarkupExtension).ProvideValue(provider);
return Compare(targetObject.GetValue(targetProperty), Comparand, Operation);
}
return false;
}
private static bool Compare(object source, object target, ComparisonOperation op)
}
最後に、このMEを使用して、各ボタンの「有効化」条件をテストしました。ここでまずボタンの条件です:
<Button (...) DataContext="{RelativeSource TemplatedParent}"
IsEnabled="{DynamicResource {mark:ComparisonBinding Path=View.CurrentPosition, RelativeSource={RelativeSource TemplatedParent}, Comparand={Binding RelativeSource={RelativeSource TemplatedParent}, Path=DataCollection.Count}, Operation=EQ}}">
残念ながら、このソリューションが動作しませんでした。このデザインタイムの例外が発生し続ける:
InvalidOperationException:ビューツリーの一部ではないViewNodeのNodePathを取得できません。
誰かがより良い解決策を持っていますか?多分私は大砲でフライを殺そうとしています。 :)
ありがとうございます。 Eduardo Melo
こんにちは、アレックス!私はWPFと.NETフレームワークが初めてです。最近私はコマンドについて読んだことがあり、それが目的です。あなたの考え方に沿って、私はそれが私が提案したものより良い解決策であることに気付きました。しかし、私が得られなかったのは、あなたが話したマイクロビューモデルです。もう少し詳しく説明できますか?ありがとう! – EdMelo
私はMVVMパターンが大好きなので、ViewModelはどこにでも言及したいと思っています。実際には、適切なパラメータを受け取ったCommandオブジェクト自体を含め、コマンドを扱うコードをどこにでも置くことができます。私の通常の最初の本能は、ロジックを処理するViewModelにそれを配置し、そのViewModelをView(この場合はコントロール)に関連付けさせることです。しかし、ユーザーコントロールの開発では、コントロール自体のICommandを定義し、ControlTemplateのTemplatedParentを使用してICommandsをバインドするだけで多くの成功を収めました。 –