2016-05-03 7 views
1

Ich versuche, mehrere TabItem dynamischcally in jeder Registerkarte ein Textfeld zu erstellen. Dann möchte ich jedes Textfeld an einen Wörterbuchindex binden. Zum BeispielBind TextBox zu Dictionary

TAB1 | TAB2 | TAB3

TextBox1 | TextBox2 | TextBox3

Dictionary [TAB1] binden an TextBox1 ... etc

ich das tue:

Dictionary<string, string> dic = new Dictionary<string, string>(); 

      Binding binding = new Binding(); 
      binding.Source = dic[id]; 
      binding.Path = ??? 

      TextBox stb = new TextBox() 
      { 
       Name = "tb" + id 

      }; 
      stb.SetBinding(TextBox.Text, binding); 

Was soll ich in den Weg legen?

Antwort

2

Sie können dies dynamisch mit Ansichtsmodellen erstellen: 1. Erstellen Sie ein Hauptansichtsmodell, um Registerkarten zu halten.

public class MainViewModel 
{ 
    private ObservableCollection<TabViewModel> tabs = new ObservableCollection<TabViewModel>(); 


    public ObservableCollection<TabViewModel> Tabs 
    { 
     get { return this.tabs; } 
    } 
} 
  1. TabViewModel erstellen, die das Wörterbuch und Header angezeigt wird halten. In diesem Beispiel ist header der Schlüssel für das Wörterbuch, aber Sie können es erweitern.

    öffentliche Klasse TabViewModel { private readonly Wörterbuch Wörterbuch;

    public TabViewModel(Dictionary<string, string> dictionary) 
        { 
         this.dictionary = dictionary; 
        } 
    
        public string Header { get; set; } 
        public string TextValue { 
         get { return this.dictionary[Header]; } 
         set { this.dictionary[Header] = value; }} 
    } 
    
  2. Erstellen Sie die tabcontrol Itemssource verwendet:

    <TabControl VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ItemsSource="{Binding Path=Tabs}" > 
         </TabControl> 
    
  3. den Stil, um es

    <Style TargetType="TabItem"> 
     
            <Setter Property="Header" Value="{Binding Path=Header}"/> 
     
            <Setter Property="ContentTemplate"> 
     
             <Setter.Value> 
     
              <DataTemplate DataType="sOfExamples:TabViewModel"> 
     
              <TextBox Text="{Binding Path=TextValue}"></TextBox> 
     
              </DataTemplate> 
     
             </Setter.Value> 
     
            </Setter> 
     
           </Style>

    = "5">

  4. Den Datenkontext zuweisen:

    MainViewModel mainViewModel = new MainViewModel(); Wörterbuch Wörterbuch = neues Dictionary(); dictionary.Add ("Header1", "Header 1 Text"); dictionary.Add ("Header2", "Header 2 text");

     mainViewModel.Tabs.Add(new TabViewModel(dictionary) 
         { 
          Header = "Header1" 
         }); 
         mainViewModel.Tabs.Add(new TabViewModel(dictionary) 
         { 
          Header = "Header2" 
         }); 
    
         this.DataContext = mainViewModel; 
    

Sie können INotifyPropertyChanged auf tabviewmodel implementieren, wenn Sie zwei Wege Update verbindlich werden soll.

+0

Vielen Dank für die Erklärung. Ich werde das versuchen und Feedback geben –

1

Ein paar Dinge zu hier bemerken:

  1. Um in der Lage sein, um es zu binden, muss das Wörterbuch ein öffentliches Eigentum sein:

    public Dictionary<string, string> dic { get; set; } = new Dictionary<string, string>(); 
    
  2. eine Bindung an das Textfeld anwenden zu können 'Text Eigenschaft, müssen Sie die Abhängigkeitseigenschaft bezieht sich nicht auf seinen Wert:

    stb.SetBinding(TextBox.TextProperty, binding); 
    
  3. Schließlich vermischen Sie die Source und Path Eigenschaften der Bindung: binding.Path ist, wo das eigentliche Bindungsziel gehört, während Source bezieht sich auf das Objekt, das dieses Ziel enthält, in diesem Fall das ist die aktuelle Klasse (alternativ ist es möglich, zu setzen das Textfeld‘DataContext Eigenschaft, die dann als verbindliche Quelle für alle seine Bindungen) automatisch angewendet:

    binding.Source = this; 
    binding.Path = new PropertyPath("dic[" + id "]"); 
    

jedoch die elegantere Lösung wird die gesamte Registerkarte Elemente binden, wie in Avneesh Antwort beschrieben .