2010-10-13 9 views
7

Ho un DataSet associato allo Window.DataContext; Ho anche un DataGrid:Collegamento a DataContext all'esterno corrente Elementi Contesto di origine

<DataGrid ItemsSource={Binding Tables[Items]}> 
    <DataGrid.Columns> 
     <DataGridTextBoxColumn Header={Binding Path=DataContext.Tables[Names]/Test, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}} /> 
    </DataGrid.Columns> 
</DataGrid> 

Fondamentalmente, io sto cercando di impegnare l'intestazione di colonna per DataTable "Nomi", colonna "Test", prima fila.

Tuttavia, non riesco a farlo bene. Nota che posso vincolarlo bene al di fuori di DataGrid. L'elemento Items della griglia modifica il contesto dei dati e non so come fare riferimento all'esterno del DataContext originale.

Sembra che la rilegatura abbia esito positivo; ma il problema è che l'oggetto corrente (prima riga) delle Tabelle [Nomi] nel Window.DataContext si è perso.

Se eseguo il DataSet statico e lo accedo tramite {x: Statico locale: set di dati}, allora le cose funzionano correttamente. Ma non posso usare set di dati statici perché ci saranno più istanze (multiutente).

Qualcuno può indicarmi la giusta direzione?

risposta

0

Non so se questo funzionerà per te, ma potresti provare qualcosa come: 1) Assegna alla tua finestra un attributo Nome, per es. Nome = ZeWindow. 2) Associare l'intestazione DataGridTextBoxColumn in questo modo:

<DataGridTextBoxColumn Header="{Binding Path=DataContext.Tables[Names]/Text, ElementName=ZeWindow}"/> 

Quindi, in pratica, invece di legame al DataContext del DataGrid, si associa alla DataContext del UIElement con Name = ZeWindow.

PS: Sono abbastanza nuovo a WPF, quindi questo potrebbe non funzionare con la finestra, ma ho fatto qualcosa di simile con UserControls

+0

Ho provato anche questo. Dà lo stesso risultato del metodo FindAncestor nel mio post. Cioè: si collega con successo, ma il "CurrentItem" del DataContext originale si è perso. Il colpevole del mio problema è che sto cercando di riferirmi a un altro DataTable che ha il suo CurrentItem (riga [0]); se mi riferisco solo a una proprietà semplice, il tuo metodo e FindAncestor funzionerebbero bene. – vuduy

+0

Ok, vedo, quindi mi dispiace ma non so quale potrebbe essere il problema. Speriamo che qualcun altro lo sappia –

10

Sono abbastanza sicuro che si potrebbe fare quello che stai cercando di fare da utilizzando il binding RelativeSource.

<DataGrid ItemsSource="{Binding StringCollection}" 
      AutoGenerateColumns="False"> 
    <DataGrid.Columns> 
    <DataGridTextColumn Binding="{Binding}" /> 
    <DataGridTextColumn Binding="{ 
          Binding RelativeSource={ 
          RelativeSource FindAncestor, 
          AncestorType={x:Type Window}}, 
          Path=DataContext.SomethingOutsideDataContext}" /> 
    </DataGrid.Columns> 
</DataGrid> 

ho fatto un rapido esempio a: http://bitbucket.org/claus/wpf-bindingoutsidedatacontext

Esso consente di associare alla finestra padre, che nel mio caso ha il ViewModel come DataContext (con la proprietà SomethingOutsideDataContext su di esso).

Si dovrebbe essere consapevoli però, questo funzionerà solo con WPF e non con Silverlight - il materiale "FindAncestor, AncestorType" non è ancora stato implementato in Silverlight ... Non sono sicuro che ci sia un altro metodo, oltre all'utilizzo statico risorse.

+0

Se non funziona per te, per favore aggiungi un piccolo esempio della struttura dell'oggetto Tabelle [Articoli]/Tabelle [Nomi] che stai cercando di associare, e vedrò se puoi creare un esempio usando quello ... – Claus

+0

Assicurati anche che il tuo tipo di antenato sia un tipo di 'Window' e non un tipo di 'UserControl' dato che la proprietà' DataContext' presenterà 'null' – Kitson88

0

Questo è il comportamento previsto in realtà: il DataContex t per DataGridCell è l'intera barra.

in modo da avere 3 soluzioni: o si aggiunge il legame in codice dietro in questo modo:

nel costruttore di ciascuna colonna:

string source = String.Format(CultureInfo.InvariantCulture, "[{0}].", thisColumnIndex); 
base.Binding = new Binding(source + "Text"); 

(devi trovare un modo per ottenere il "thisColumnIndex "Per quanto mi riguarda, aggiungo le colonne subito dopo averle create, io semplicemente inserisco" dataGridOwner.Columns.Count "lì).

oppure ...

è possibile trovare un modo per ottenere il DataContext che si desidera su ogni cella (provato, ma si scombina male quando virtualizzazione colonna/riga è acceso)

o ...

uno sguardo lì :

Binding a cell object's property to a DataGridCell in WPF DataGrid

personalmente trovo il primo a essere il meglio per il mio scopo (da quando aggiungo le mie colonne in codice dietro comunque), ma questo è davvero a voi, alla fine ...


Per quanto riguarda ColumnHeaders sono interessati (e solo columnsHeaders, non le righe), si potrebbe anche esplorare il modo in cui "DataTemplate":

impostare intestazione delle colonne per la colonna stessa (in questo modo si imposta la colonna come DataContext per l'intestazione) e utilizzare un DataTemplate.

esempio:

in ogni classe della colonna:

private static DependencyProperty ColumnHeaderProperty = DependencyProperty.Register("ColumnHeader", typeof(MyDataGridColumnHeader), typeof(MyTextBoxColumn)); 
public MyDataGridColumnHeader ColumnHeader 
{ 
    get { return (MyDataGridColumnHeader)(GetValue(ColumnHeaderProperty)); } 
    set { SetValue(ColumnHeaderProperty, value); } 
} 

this.ColumnHeader = new MyDataGridColumnHeader(); 
Header = this; 

e nel tuo XAML DataGrid, qualcosa di simile:

<DataGrid.ColumnHeaderStyle> 
    <Style TargetType="{x:Type DataGridColumnHeader}"> 
     <Style.Setters> 
      <Setter Property="HorizontalContentAlignment" Value="Stretch"/> 
      <Setter Property="VerticalContentAlignment" Value="Stretch"/> 
      <Setter Property="BorderThickness" Value="{Binding BorderThickness}" /> 
      <Setter Property="BorderBrush" Value="{StaticResource DataGridLinesBrush}" /> 
      <Setter Property="Background" Value="{StaticResource DataGridColumnHeaderBackground}" /> 

      <Setter Property="FontFamily" Value="{Binding ColumnHeader.Font.Family, TargetNullValue={StaticResource DefaultFontFamily}}" /> 
      <Setter Property="FontSize" Value="{Binding ColumnHeader.Font.Size, TargetNullValue={StaticResource DefaultFontSize}}" /> 
      <Setter Property="FontStyle" Value="{Binding ColumnHeader.Font.Style, TargetNullValue=Normal}" /> 
      <Setter Property="FontWeight" Value="{Binding ColumnHeader.Font.Weight, TargetNullValue=Bold}" /> 
      <Setter Property="Foreground" Value="{Binding ColumnHeader.Font.Brush, TargetNullValue={StaticResource DataGridColumnHeaderForeground}}" /> 

      <Setter Property="ContentTemplate"> 
       <Setter.Value> 
        <DataTemplate> 
         <Grid Background="{Binding ColumnHeader.Background}"> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="Auto" /> 
           <ColumnDefinition Width="*" /> 
           <ColumnDefinition Width="Auto" /> 
          </Grid.ColumnDefinitions> 
          <Image Name="LeftImage" Grid.Column="0" Stretch="None" Margin="3, 0, 0, 0" Source="{Binding ColumnHeader.LeftImage}" VerticalAlignment="Center"/> 
          <Image Name="RightImage" Grid.Column="2" Stretch="None" Margin="0, 0, 5, 0" Source="{Binding ColumnHeader.RightImage}" VerticalAlignment="Center"/> 
          <TextBlock Name="HeaderText" 
             Grid.Column="1" 
             VerticalAlignment="Center" 
             HorizontalAlignment="Center" 
             TextDecorations="{Binding ColumnHeader.Font.Decorations}" 
             Text="{Binding ColumnHeader.Text}" /> 
         </Grid> 
        </DataTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style.Setters> 
    </Style> 
</DataGrid.ColumnHeaderStyle> 

naturalmente, la mia classe "MyDataGridColumnHeader" contiene definizioni per tutti le proprietà a cui si fa riferimento qui.

spero che questo aiuti.