2011-01-25 7 views
0

ユーザーコントロールはControls \ TabControlにあります。 2つのタブアイテム(RuleTabとDiagramTab)を持つタブコントロールが含まれています。私は私のMainWindowViewmodelクラスでWPFリファレンスMainWindowViewModelコードでのユーザーコントロール

:それがユーザーコントロールにだから

private void ShowSaveDialog() 
    { 
     System.Windows.Forms.SaveFileDialog sfd = new System.Windows.Forms.SaveFileDialog(); 
     sfd.Filter = "Text File (*.txt)|*.txt"; 

     bool? saveResult = sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK; 

     if (saveResult == true) 
     { 
      string s = sfd.FileName; 
      filePath = s; 
      SaveFile(s); 
      SetTitle(sfd.FileName); 
      RuleTab.Header = new System.IO.FileInfo(sfd.FileName).Name; 
      RuleTab.Focus(); 
     } 

RuleTab(のTabItem)が発見されていません。私はどのように私のクラスでそれを正しく参照するのですか?

TabControl.xaml

  x:Name="TabEditor" x:FieldModifier="public" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="423"> 

<TabControl x:Name="tabControl" x:FieldModifier="public" Width="Auto" Padding="0" Margin="3" DataContext="{Binding}"> 
    <local:CloseableTabItem Header="Diagram" x:Name="DiagramTab" x:FieldModifier="public" Height="25"> 
     <Image Height="Auto" x:Name="ResultImage" x:FieldModifier="public" Stretch="Fill" Width="Auto" /> 
    </local:CloseableTabItem> 
    <local:CloseableTabItem Header="Rulebase" x:Name="RuleTab" x:FieldModifier="public" Height="25" > 
     <Grid> 
      <TextBox Height="Auto" x:Name="RuleText" x:FieldModifier="public" Width="Auto" Text="" AcceptsTab="True" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Visible" /> 
     </Grid> 
    </local:CloseableTabItem> 
</TabControl> 

答えて

1

あり、様々な可能性があるが、私はあなたのコードの例を見れば、私は私があなたのViewModelにイベントFileSavedを追加し、sucessfull後にこのイベントを発生させるだろうと思います節約する。
MainWindowから、このイベントに登録して、目的のコントロールにフォーカスを当てるなどの処理を行うことができます。
しかし、ヘッダーを設定するには、ViewModelでプロパティを宣言し、RuleTabsヘッダーをバインドします。しかし、明らかにイベントのヘッダーを設定することもできますが、これにはいくつかの不必要な欠点があります。

更新
ここでイベントとあなたのViewModel内のプロパティを実装するための簡単な例として希望。あなたのViewModelはINotifyPropertyChangedを実装していると仮定します。ではないが、それはDependencyObjectから派生した場合は、代わりにCLR-プロパティのFileNameのために、読み取り専用DepencencyPropertyを宣言:

string m_fileName; 
public event EventHandler FileSaved;  

private void ShowSaveDialog() 
    { 
     System.Windows.Forms.SaveFileDialog sfd = 
      new System.Windows.Forms.SaveFileDialog(); 
     sfd.Filter = "Text File (*.txt)|*.txt"; 

     bool? saveResult = sfd.ShowDialog() == System.Windows.Forms.DialogResult.OK; 

     if (saveResult == true) 
     { 
      string s = sfd.FileName; 
      filePath = s; 
      SaveFile(s); 
      FileName=sfd.FileName; 
      OnFileSaved(EventArgs.Empty); 
     } 
} 

protected virtual void OnFileSaved(EventArgs e){ 
    if(null != FileSaved){ 
     FileSaved(this,e); 
    } 
} 

public string FileName{ 
    get{return m_fileName;} 
    private set{ 
     if(value!=m_fileName){ 
      m_fileName=value; 
      OnPropertyChanged(new PropertyChangedEventArgs("FileName")); 
     } 
    } 
} 
+0

両方のコードサンプルを教えてもらえますか? –

0

WPFはUserControlprivateなどのコントロールを宣言します。 xは、XAML名前空間xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"ある

<TextBox x:FieldModifier="Public" /> 

:あなたのRuleTabpublicを作るために、あなたはFieldModifierのようにそれを宣言します。

+0

ああ、小文字の "public" ...ありがとう:) –

+0

x:FieldModifierをpublicに設定した後でも、私のMainWindowViewModelクラス(RuleTab.Header =新しいSystem.IO.FileInfo(ofd.FileName).Name; ....任意の提案はおそらく? –

+0

@mr justinator:これは、(適切に)MainWindowへの参照を持っていない限り、これはできませんこのリファレンスをViewModelに直接与えることはお勧めできませんMVVMパターンの柔軟性が失われてしまいますので、イベントとFileNameプロパティの作成をお勧めします。あなたが望むのであれば、テキストボックス(例えばTomBotが書いたもの)に直接焦点を当てることができますが、私はusercontrolに焦点を合わせ、usercontrolがTextBoxにフォーカスを移しているように見えます。 ) – HCL

0

MVVMパターンを使用していますか?コントロールのプロパティにアクセスせず、コントロールがバインドされているビューモデルのプロパティにアクセスします。

RuleTabのビューモデルが必要です。 RuleTabHeaderがバインドされているFilenameプロパティが公開されている必要があります。あなたのメソッドは、そのプロパティを設定します。 (もちろん、通常の方法のいずれかで変更通知を実装する必要があります)

一般に、ビューモデルコードでコントロールを操作しようとすると、間違っていることがあります。ビューモデルはコントロールが存在することを知らない。 NUnitであなたのビューモデルの単体テストを記述することはほとんどありません(誰も話しませんが、人はほとんどありません)が、少なくともできるはずです。

また、ファイルダイアログを表示するメソッドは、ビューモデルではなくビュー内のメソッドでなければなりません。これは少しのアーキテクチャ - astronautyを取得しますが、一般的な考えは、ビューモデルにはUIがまったくないということです。これに対処する一般的な方法は、実行時にイベントを発生させるSaveCommandを実装するビューモデルと、実際にファイルを保存するパブリックメソッドを持つことです。ビューはイベントをリッスンし、イベントが発生するとダイアログを表示し、ファイル名を取得し、ユーザーがキャンセルしなかった場合はビューモデルのメソッドを呼び出します。これは、UIを使わずに単体テストを書くことができるものです。

+0

私はMVVMモデルを使用しようとしていますはい:私はそれを明らかに把握することは非常に困難です!私はこのアプリを作って、このモデルを使って再構築しようとしていますが、はるかに難しいようです。私はより多くのコードサンプルを見つけようとします。応答する時間をとっていただきありがとうございます。 –

+0

MVVMの方がはるかに簡単です。ビューモデルが 'ListBox'にバインドされているときに' SelectedItem'プロパティを実装し、それに 'ListBox.SelectedItem'をバインドするのに慣れていなければならない小さなサブパターンがたくさんありますいったんあなたの頭の中にいれば、それはあなたの睡眠中にできることになります。私は1年前に書いたWinFormsのアプリケーションを修正しています。本当に非常にシンプルなUIの中では非常に複雑なコードが私を泣かせてくれます。ビューモデルを実装してバインドするだけであれば、はるかに簡単に*できます。 –

関連する問題