2012-01-08 4 views
14

Ho un Datagrid dinamico che ho creato. Sto creando ogni colonna per esso attraverso il codice dietro. Ho problemi su una colonna che desidero visualizzare in un blocco di testo quando non si modifica, ma come una combobox durante la modifica. Ho una ObservableCollection of Transactions. Ogni Transazione ha un tipo chiamato "Account". Ecco cosa ho finora:Crea DataGridTemplateColumn attraverso il codice C#

private DataGridTemplateColumn GetAccountColumn() 
    { 
     // Create The Column 
     DataGridTemplateColumn accountColumn = new DataGridTemplateColumn(); 
     accountColumn.Header = "Account"; 

     Binding bind = new Binding("Account"); 
     bind.Mode = BindingMode.TwoWay; 

     // Create the TextBlock 
     FrameworkElementFactory textFactory = new FrameworkElementFactory(typeof(TextBlock)); 
     textFactory.SetBinding(TextBlock.TextProperty, bind); 
     DataTemplate textTemplate = new DataTemplate(); 
     textTemplate.VisualTree = textFactory; 

     // Create the ComboBox 
     bind.Mode = BindingMode.OneWay; 
     FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(ComboBox)); 
     comboFactory.SetValue(ComboBox.DataContextProperty, this.Transactions); 
     comboFactory.SetValue(ComboBox.IsTextSearchEnabledProperty, true); 
     comboFactory.SetBinding(ComboBox.ItemsSourceProperty, bind); 

     DataTemplate comboTemplate = new DataTemplate(); 
     comboTemplate.VisualTree = comboFactory; 

     // Set the Templates to the Column 
     accountColumn.CellTemplate = textTemplate; 
     accountColumn.CellEditingTemplate = comboTemplate; 

     return accountColumn; 
    } 

Il valore viene visualizzato in TextBlock. Tuttavia, nella casella combinata, visualizzo solo un carattere per elemento. Ad esempio, ecco il blocco di testo:

enter image description here

Ma quando clicco per modificare e andare nella casella combinata, ecco ciò che viene mostrato:

enter image description here

Qualcuno mi può aiutare in modo che gli elementi nel Combobox sono visualizzati correttamente? Inoltre, quando seleziono qualcosa da Combobox, il blocco di testo non viene aggiornato con l'elemento selezionato.

aggiornamento:

Qui è la mia colonna, al momento. Gli elementi nel ComboBox vengono visualizzati correttamente. Il problema ora è che quando viene selezionato un nuovo elemento, il testo in TextBlock non viene aggiornato con il nuovo elemento.

private DataGridTemplateColumn GetAccountColumn() 
    { 
     // Create The Column 
     DataGridTemplateColumn accountColumn = new DataGridTemplateColumn(); 
     accountColumn.Header = "Account"; 

     Binding bind = new Binding("Account"); 
     bind.Mode = BindingMode.OneWay; 

     // Create the TextBlock 
     FrameworkElementFactory textFactory = new FrameworkElementFactory(typeof(TextBlock)); 
     textFactory.SetBinding(TextBlock.TextProperty, bind); 
     DataTemplate textTemplate = new DataTemplate(); 
     textTemplate.VisualTree = textFactory; 

     // Create the ComboBox 
     Binding comboBind = new Binding("Account"); 
     comboBind.Mode = BindingMode.OneWay; 

     FrameworkElementFactory comboFactory = new FrameworkElementFactory(typeof(ComboBox)); 
     comboFactory.SetValue(ComboBox.IsTextSearchEnabledProperty, true); 
     comboFactory.SetValue(ComboBox.ItemsSourceProperty, this.Accounts); 
     comboFactory.SetBinding(ComboBox.SelectedItemProperty, comboBind); 

     DataTemplate comboTemplate = new DataTemplate(); 
     comboTemplate.VisualTree = comboFactory; 

     // Set the Templates to the Column 
     accountColumn.CellTemplate = textTemplate; 
     accountColumn.CellEditingTemplate = comboTemplate; 

     return accountColumn; 
    } 

La proprietà "Account" viene dichiarato come questo nella mia classe MainWindow:

public ObservableCollection<string> Accounts { get; set; } 

    public MainWindow() 
    { 
     this.Types = new ObservableCollection<string>(); 
     this.Parents = new ObservableCollection<string>(); 
     this.Transactions = new ObservableCollection<Transaction>(); 
     this.Accounts = new ObservableCollection<string>(); 

     OpenDatabase(); 
     InitializeComponent(); 
    } 

Qui è la mia classe di transazione:

public class Transaction 
{ 
    private string date; 
    private string number; 
    private string account; 

    public string Date 
    { 
     get { return date; } 
     set { date = value; } 
    } 

    public string Number 
    { 
     get { return number; } 
     set { number = value; } 
    } 

    public string Account 
    { 
     get { return account; } 
     set { account = value; } 
    } 
} 
+0

Non si dovrebbe riutilizzare la stessa istanza di bind per collegamenti diversi ... –

risposta

3

si associa il ItemsSource al valore selezionato, una stringa, ovvero un array di caratteri, in modo che ogni carattere venga utilizzato come elemento, presumibilmente il collegamento ItemsSource deve essere indirizzato ad altre raccolte da cui il valore può essere ch Osen.

+0

Ahh sì che ha senso! Grazie per le informazioni! Ho aggiunto il codice in modo che la fonte di elementi provenga da una collezione diversa ora. Gli elementi nella casella combinata appaiono come dovrebbero. Un'altra cosa però, quando seleziono un valore diverso dalla casella combinata, il blocco di testo non viene aggiornato con il nuovo elemento. Come lo risolverei? –

+0

@EricR .: Bind il 'SelectedItem' o' SelectedValue' a 'Account'. Usa 'SelectedItem' se gli elementi sono già stringhe che dovrebbero essere usate come valore per l'account, usa [' SelectedValue'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives .selector.selectedvalue.aspx) in combinazione con ['SelectedValuePath'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.selector.selectedvalue.aspx) se il valore è una proprietà sull'elemento selezionato (e non sull'oggetto stesso). –

+0

Come dovrei farlo? La nuova raccolta per gli account che sto utilizzando è ObservableCollection . Sto settando ora l'oggetto Items da questo: comboFactory.SetValue (ComboBox.ItemsSourceProperty, this.Accounts) ;. questo.Account è ObservableCollection. Quindi, come faccio a impostare SelectedItem per questo? Apprezzo davvero tutto l'aiuto che mi hai dato finora! –

0
Dim newBind As Binding = New Binding("LinktoCommonOutputBus") 
newBind.Mode = BindingMode.OneWay 

factory1.SetValue(ComboBox.ItemsSourceProperty, dictionary) 
factory1.SetValue(ComboBox.NameProperty, name) 
factory1.SetValue(ComboBox.SelectedValuePathProperty, "Key") 
factory1.SetValue(ComboBox.DisplayMemberPathProperty, "Value") 
factory1.SetBinding(ComboBox.SelectedValueProperty, newBind) 

Creando Binding è possibile impostare SelectedValue in un datagrid per WPF.