0

私は WPF とデータ バインディングに慣れていないので、調査で何かを簡単に見逃したり、解決策を見つけるために間違った検索用語を使用したり (可能性が高い) したりしました。

バインディングの値がオブジェクトへの参照ではなく渡されているように見えるため、値が背後のコードで設定されても更新されません。

OpenFileDialog を一般化して、タブ コントロールのいくつかの異なるタブで役立つようにしようとしています。パラメータ (Path、Filter、および TextBox) を保持するカスタム データ オブジェクトを作成しました。

class OpenFileCommandParameters
{
    public string Filter { get; set; }
    public string Path { get; set; }
    public string TextBox { get; set; }
}
class OpenFileCommandParamtersConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        OpenFileCommandParameters parameters = new OpenFileCommandParameters();
        if (values[0] is string) parameters.Filter = (string)values[0];
        if (values[1] is string) parameters.Path = (string)values[1];
        if (values[2] is string) parameters.TextBox = (string)values[2];
        return parameters;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

情報を渡すための XAML は次のようになります。

<TextBox Name="ButtonTagImportFileName" Text="{Binding Path=TagImportTabVM.TbFileName}" Height="23" HorizontalAlignment="Left" Margin="83,17,0,0" VerticalAlignment="Top" Width="221" />
<Button Name="TagImportOpenFile" Content="Open File" Command="{Binding Path=OpenFileCommand}" Height="23" HorizontalAlignment="Left" Margin="342,17,0,0" VerticalAlignment="Top" Width="98" >
  <Button.CommandParameter>
      <MultiBinding Converter="{StaticResource openFileCommandParametersConverter}">
          <MultiBinding.Bindings>
              <Binding Source="XML files (*.xml)|*xml|All files (*.*)|*.*"/>
              <Binding Path="AppPath"/>
              <Binding Path="TagImportTabVM.TbFileName"/>
          </MultiBinding.Bindings>
      </MultiBinding>
  </Button.CommandParameter>

テキスト ボックスと [ファイルを開く] ボタンの両方に、同じ文字列プロパティへのバインドがあります。

プロパティは、コマンドの実行によって更新されます

private void OpenFile(object parameter)
    {
       var parameters = parameter as OpenFileCommandParameters;
       FileDialog.Filter = parameters.Filter;
       FileDialog.InitialDirectory = parameters.Path;
       if (parameters == null) return;
       var result = FileDialog.ShowDialog();
       if (result == true)
       {
           parameters.TextBox = FileDialog.SafeFileName;
       }
    }

このコマンドが終了したら、TbFileName の値はファイル ダイアログからの値と同じになると思います。これはそうではありません。OpenFile ブロックの終了直前のブレーク ポイントから見た場合。

ここに画像の説明を入力

あなたが私に提供できる支援に感謝します。

4

2 に答える 2

0

私はほとんど解決策にたどり着いており、@a little sheep は彼の解決策の残りの道を私に教えてくれました。質問を完全にまとめたかっただけです。

ソースが更新されていないため、コードで値を設定しているときにバインディングが壊れていると考えていました。これはそうではありません。単に値が変更されたことを知らなかったため、ソースを更新することを知らなかったのです。

これを発見すると、ソースを更新する必要があることをシステムに通知する方法を見つけるのは簡単でした. これはに追加されますprivate void OpenFile(object parameter)

BindingExpression binding = BindingOperations.GetBindingExpression(parameters.PassedTextBox, TextBox.TextProperty);
binding.UpdateSource();

適切に更新するために追加されたのはそれだけです。

于 2012-07-30T17:19:15.300 に答える
0

MultiBinding はそのソース バインディングを更新しようとしないため、これは機能しないと思います。これをどうにか強制することもできるかもしれませんが、使ってみたところ

BindingOperations.GetBindingExpression(TagImportOpenFile, Button.CommandParameterProperty)

常に null を返すため、CommandParameters をバインドするアプローチが機能するかどうかはわかりません。CommandProperty の式の取得は正常に機能します。CommandParameters は異なる必要があります...どういうわけか。

間違いなく機能するこれを行う方法は次のようになると思います:

a) パラメータ クラスを ViewModel に変換します (または、少なくとも双方向バインディングの場合は INotifyPropertyChanged/DependencyObject にします)。TextBox プロパティの名前を「FileName」などに変更する必要があります。

b) このクラスのインスタンスを画面 ViewModel (この場合は「TagImportTabVM」?) に配置します。

c) XAML を次のように変更します。

<TextBox Name="ButtonTagImportFileName" Text="{Binding Path=OpenFileVM.FileName}" Height="23" HorizontalAlignment="Left" Margin="83,17,0,0" VerticalAlignment="Top" Width="221" />
<Button Name="TagImportOpenFile" Content="Open File" Command="{Binding Path=OpenFileCommand}" CommandParameter="{Binding OpenFileVM}" 
        Height="23" HorizontalAlignment="Left" Margin="342,17,0,0" VerticalAlignment="Top" Width="98" />

これは、パラメーターの新しいインスタンスを作成するときに、コードでファイル フィルターを設定してもかまわないことを前提としています (とにかく、AppPath に対してこのようなことをしたと仮定したため)。

于 2012-07-19T23:13:08.037 に答える