2

プログラマーの皆さん、こんにちは。IDataErrorInfoを使用したSilverlightMVVMパターンでこの奇妙な問題が発生します。これはStackOverflowでの最初の質問なので、正しく説明できればと思います。取引は次のとおりです。

HasPrevisionというチェックボックスがオンになっている場合にのみ有効にする必要があるいくつかのコントロールを備えたこの巨大なJobRegisterChildWindowがあります。アイデアは次のとおりです。ジョブにプレビジョンがある場合、プレビジョンに関連するすべてのコントロールが有効になり、そうでない場合は無効になります。ここで、プレビジョンがある場合、ユーザーはPrevisionTypeComboBoxでプレビジョンタイプを選択する必要があります。したがって、HasPrevisionチェックボックスがチェックされている場合はPrevisionTypeを選択する必要がありますが、HasPrevisionチェックボックスがチェックされていない場合はPrevisionTypeコンボボックスを選択しないままにしておくことができます。

これらのコントロールのXAMLは次のとおりです(かなり大きいため、ここではすべてのxamlを表示しませんが、これらの行を表示するだけで問題を解決できると思います):


<!-- The HasPrevision CheckBox -->
<CheckBox Grid.Column="1"
  Grid.Row="3"
  x:Name="cbxHasPrevision"
  IsChecked="{Binding SelectedJob.HasPrevision, Mode=TwoWay}"
  Margin="0,20,2,0" />

<!-- The PrevisionType ComboBox -->
<telerik:RadComboBox Grid.Column="1"
  Grid.Row="4"
  x:Name="cmbPrevisionType"
  IsEnabled="{Binding HasPrevision, Converter={StaticResource ControlesCadastroProcessoConverter}, ConverterParameter=IsEnabled}"
  ItemsSource="{Binding PrevisionTypeList, Mode=OneWay}"                             
  SelectedItem="{Binding SelectedJob.PrevisionType , Mode=TwoWay, NotifyOnValidationError=True, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}"
  Margin="0,4,48,4"
  Height="22"
  DisplayMemberPath="DsPrevisionType"/>

したがって、ご覧のとおり、HasPrevisionプロパティとPrevisionTypeプロパティは、SelectedJobという名前のViewModelのプロパティにバインドされています。SelectedJobはJobオブジェクトです。私がやりたいのは、ジョブクラスのIDataErrorInfoインターフェイスを使用して、PrevisionTypeが選択されているかどうかを識別することです。現在、HasPrevisionプロパティが「true」の場合にのみPrevisionTypeを要求できるため、ジョブクラスにはIDataErrorInfoの次のコードがあります。


public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "PrevisionType":                      
                    if (HasPrevision && (PrevisionType== null))
                        return "Select a PrevisionType";
                    break;
            }
            return null;
        }

}

これは私には非常に論理的に聞こえます。コードをデバッグすると、実際に機能します。スイッチはcolumnNameを識別し、ケース「PrevisionType」を入力し、デフォルトの「return null」句ではなく、エラーメッセージを返すIfステートメント内で実際にリターンコードを実行します。ただし、エラーメッセージにはエラーは表示されません。さらに悪いことに、コンボボックスはイベントを自動的に検証しません。[保存]ボタンをクリックすると、エラーをチェックし、PrevisionTypeコンボボックスをInvalidFocused状態に設定します。comboBoxは、エラー状態にあることを示す赤い境界線を取得しますが、エラーメッセージは空白です。コントロールのマウスにカーソルを合わせると、何も表示されていない空の小さな赤いボックスが表示されます。

それよりもさらに奇妙です。IFステートメントから「HasPrevision」チェックを削除し、コードを次のように残すと、メッセージが表示され、コントロールが自動的に検証されます!!!


public string this[string columnName]
    {
        get
        {
            switch (columnName)
            {
                case "PrevisionType":                      
                    if (PrevisionType== null)
                        return "Select a PrevisionType";
                    break;
            }
            return null;
        }
    }

私が考えることができるのは、別のプロパティ値に基づいてプロパティを検証しようとしているため、Silverlight環境が「混乱」するということです。わからない、私はこれの解決策を2日間見つけようとしていたが、成功しなかった。これが私が関連すると信じている他のコードのいくつかです。

私のジョブクラスのプロパティ:


    private bool _HasPrevision;
    [DataMember]
    public bool HasPrevision
    {
        get { return _HasPrevision; }
        set
        {
            _HasPrevision= value;
            RaisePropertyChanged("HasPrevision");
        }
    }


    private PrevisionType.PrevisionType _PrevisionType { get; set; }
    [DataMember]
    public PrevisionType.PrevisionType PrevisionType
    {
        get { return _PrevisionType; }
        set
        {
            _PrevisionType = value;
            RaisePropertyChanged("PrevisionType");
        }
    }

ViewModelのSelectedJobプロパティは次のとおりです。


public const string SelectedJobPropertyName = "SelectedJob";
    private Objects.Register.Job.Job _SelectedJob = null;
    public Objects.Register.Job.Job SelectedJob
    {
        get
        {
            return _SelectedJob;
        }

        set
        {
            if (_SelectedJob == value)
                return;

            var oldValue = _SelectedJob;
            _SelectedJob = value;
            RaisePropertyChanged(SelectedJobPropertyName , oldValue, value, true);
        }
    }

そして、保存ボタンの私のコードは次のとおりです。


[...]

if(SelectedJob["PrevisionType"] != null)
{
    VisualStateManager.GoToState(cmbPrevisionTypeControl, "InvalidFocused", true);
    return;
}

[...]

よろしくお願いします。説明に少し戸惑いましたらごめんなさい。

編集1:私はすでにここでそれらの質問を読んでいましたが、それらは私を完全には助けません:

IDataErrorInfo-ピックアップされてもエラーメッセージが表示されない

SilverlightIDataErrorInfoメッセージがカスタムコントロールのテキストボックスに表示されない

4

1 に答える 1

0

同様の方法で Telerik RadComboBox を使用していますが、エラー メッセージが表示されても問題はありません。これが参考用の私のXAMLです。これがお役に立てば幸いです...

 <TextBlock Text="Select a User to Assign the Current Step To:" Grid.Row="3" Visibility="{Binding ShowAssigneeUser}"/>
            <telerik:RadComboBox x:Name="cmbAllActiveCrmUsers" 
                                 IsEditable="True" 
                                 Grid.Row="4"                   
                                 telerik:TextSearch.TextPath="FullName" 
                                 Text="{Binding FullName, Mode=TwoWay, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"
                                 VerticalAlignment="Center"
                                 Visibility="{Binding ShowAssigneeUser}"
                                 ItemsSource="{Binding AllActiveCrmUsersExceptCurrentUser}" 
                                 SelectedIndex="{Binding DefaultAssigneeUserIndex, Mode=TwoWay}"
                                 ItemTemplate="{StaticResource ComboBoxMultilineTemplate}" 
                                 Style="{StaticResource ComboBoxStyle}"
                                 Command="{Binding AssignUserChangeCommand}"
                                 CommandParameter="{Binding SelectedIndex, ElementName=cmbAllActiveCrmUsers}"
                                  >
                <telerik:RadComboBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel />
                    </ItemsPanelTemplate>
                </telerik:RadComboBox.ItemsPanel>
            </telerik:RadComboBox>
于 2012-09-26T22:11:52.833 に答える