2017-02-02 9 views
0

動的に作成されたコントロールで構成されるウィンドウを作成しています。私はItemsControlにを使用して作成しています:ItemTemplateSelectorDataTemplate資源からのタイプに基づいて選択動的に作成されたWPFフレームワーク要素を検証する

<ItemsControl Grid.Row="0" Name="DynamicContent" ItemsSource="{Binding Path=EmbeddedInputControls}" ItemTemplateSelector="{Binding Path=EmbeddedInputControlsTemplateSelector}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 

<Window.Resources> 
    <converters:ErrorBooleanToBrush x:Key="ErrorBooleanToBrush"/> 
    <DataTemplate x:Key="EmbeddedStringInput" DataType="embeddedInputDescriptors:StringEmbeddedInputDescriptor"> 
     <StackPanel Orientation="Horizontal" Background="{Binding IsErrored, Converter={StaticResource ErrorBooleanToBrush}}"> 
     <Label Content="{Binding LabelContent}"></Label> 
     <dxe:TextEdit EditValue="{Binding TextValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}" /> 
     </StackPanel> 
    </DataTemplate> 
    <DataTemplate x:Key="EmbeddedIntegerInput" DataType="embeddedInputDescriptors:IntegerEmbeddedInputDescriptor"> 
     <StackPanel Orientation="Horizontal" Name="IntStackPanel"> 
      <Label Content="{Binding LabelContent}"></Label> 
      <dxe:SpinEdit Value="{Binding IntValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}" 
         MinValue="{Binding MinValue}" MaxValue="{Binding MaxValue}" Validate="OnValidate" Tag="{Binding Self}"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

これは、表示のために正常に動作しますが、検証は頭痛の種であることが判明しました。私はついに見つけた解決策は、コードビハインドとOnValidateイベントハンドラ使用しています:

private void OnValidate(object sender, ValidationEventArgs e) 
{ 
    var dynamicInputElement=((FrameworkElement)sender).Tag as IEmbeddedInputDescriptor; 

    var errorContent = dynamicInputElement?.ErrorContent(e.Value); 

    if(!string.IsNullOrEmpty(errorContent)) 
    { 
     e.IsValid = false; 
     e.ErrorContent = errorContent; 
    } 
} 

それは私が書かなければならなかったと私はそれを取り除くしたいのですが、私はちょうどすることができます唯一のコードビハインドですそれなしで検証を実装する方法を見ています。検証規則はビジネスロジックに基づいているので、XAMLでそれらを持つことはできません。

{Binding IsErrored, Converter={StaticResource ErrorBooleanToBrush}} 
<StackPanel.Style> 
    <Style> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding Path=IsErrored}" Value="True"> 
       <Setter Property="StackPanel.Background" Value="LightCoral"> 
        </Setter> 
     </DataTrigger> 
     </Style.Triggers> 
    </Style> 
</StackPanel.Style> 

フレームワーク要素を導き出すために使用されるオブジェクトは、次のとおりです:醜いビットを、私はそれぞれのDataTemplateにそのメンバーが関連する記述子から得たスタイルを与えたが、それがあったとき、私はほとんどのソリューションを持っ

internal interface IEmbeddedInputDescriptor 
{ 
    bool IsReadOnly { get; } 
    bool IsRequired { get; } 
    object Value { get; } 
    bool IsErrored { get; } 
    string ErrorContent(object value); 
} 

コードビハインドを取り除くとよいでしょう。私は、プロセスでWPFについてもっと有用なことを学ぶと確信しています。

さらに詳しい情報:バインディングの検証日時:エラーで

<dxe:SpinEdit Value="{Binding IntValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidationRules={Binding valRules}}" 

public IEnumerable<ValidationRule> valRules 
{ 
    get { throw new NotImplementedException(); } 
} 

結果「 'バインディングがValidationRuleCollection 'コレクション' 内で使用することはできません'。 'Binding'はDependencyObjectのDependencyPropertyでのみ設定できます。 '

私は同様にIDataErrorInfoとの問題を抱えていました。メインのビューモデルや記述子自体に実装しているかどうかにかかわらず、どちらのプロパティを呼び出すことも決してできませんでした。考えられる問題は、エラープロパティを識別する方法があるかどうかです。なぜなら、エラー値のプロパティが常に「値」であると思われるからです。これはあいまいです。実際、それはほとんどのソリューションで問題になっていました。私は応答することができたイベントをもたらしたものでした。だ

なぜTagプロパティを使用しての私の現在のソリューション・リゾート。それがなければ、フォームイベントを基になるビジネスオブジェクトにリンクするのは難しいです。

+0

あなたは['Binding.ValidationRules'](https://msdn.microsoft.com/en-us/library/ms753962%28v=vs.110%29.aspx?f=255&MSPPError=)を探している可能性があります-2147217396)。あなたは 'DataTemplate'でそれを設定することができます。それでもC#コードはありますが、それはMVVMishの方法で考慮されています。また、['IDataErrorInfo'](http://stackoverflow.com/questions/14023552/how-to-use-idataerrorinfo-error-in-a-wwf-program)を見ることもできます。これは、検証をビューモデルに入れます。 –

+0

["私はサンプルコードを壊しました!"](http://i1.kym-cdn。com/photos/images/facebook/001/016/682/379.jpeg)OK。 "そして今、それは動作しません!"はい、それはいつもの結果です。他に何かお手伝いできますか? –

+0

え?あなたは今何を提案していますか?私は無意味な記事を読むよりも良いことがあります。 –

答えて

1

答えは、私は私の記述クラス(各作成したフレームワーク要素のためのDataContextになるオブジェクト)を実装する方法に関連することが判明しました。 IDataErrorInfoを '間違った'基底クラスに実装しましたが、これはクラス階層では表示されませんでした。良い夜の眠りの後で新鮮な目で、私はそれを直ちに見つけました。そう頻繁に

方法。

関連する問題