2010-10-13 7 views
7

Tengo un DataSet vinculado al Window.DataContext; También tengo una DataGrid:Encuadernación a DataContext fuera de los elementos actuales Contexto del origen

<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> 

Básicamente, estoy tratando de obligar a la cabecera de la columna a DataTable "Nombres", columna, primera fila "de prueba".

Sin embargo, no puedo hacerlo bien. Tenga en cuenta que puedo vincularlo bien fuera de DataGrid. TheGrid's ItemsOrden cambia el contexto de datos y no sé cómo referirme fuera del DataContext original.

Parece que el enlace tiene éxito; pero el problema es que el ítem actual (primera fila) de las Tablas [Nombres] en Window.DataContext se perdió.

Si hago que el DataSet sea estático y acceda a él a través de {x: Static local: dataset}, entonces las cosas funcionan bien. Pero no puedo usar datasets estáticos porque habrá múltiples instancias (multiusuario).

¿Alguien puede señalarme en la dirección correcta?

Respuesta

0

No sé si esto funcionará para su situación, pero podría intentar algo como esto: 1) Déle a su ventana un atributo de nombre, p. Nombre = ZeWindow. 2) vincular a su DataGridTextBoxColumn encabezado así:

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

Así que, básicamente, en lugar de unirse a la DataContext del DataGrid, se asocie a la DataContext del UIElement con nombre = ZeWindow.

PS: Estoy bastante nuevo en WPF, por lo que este podría no funcionar con la ventana, pero me hizo algo similar con UserControls

+0

También probé esto. Da el mismo resultado que el método FindAncestor en mi publicación. Es decir: se une correctamente, pero el "CurrentItem" del DataContext original se perdió. El culpable de mi problema es que estoy tratando de referirme a otra DataTable que tiene su propio CurrentItem (fila [0]); si me refiero solo a una propiedad simple, entonces su método y FindAncestor funcionarían bien. – vuduy

+0

Ok, veo, entonces lo siento, pero no sé cuál podría ser el problema. Con suerte, alguien más sabrá –

10

Estoy bastante seguro de que podría hacer lo que estamos tratando de hacer por usando RelativeSource vinculante.

<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> 

hice un rápido ejemplo en: http://bitbucket.org/claus/wpf-bindingoutsidedatacontext

Se le permite enlazar a la ventana padre, que en mi caso tiene el modelo de vista como DataContext (con la propiedad SomethingOutsideDataContext en él).

Sin embargo, debe tener en cuenta que esto solo funcionará con WPF y no con Silverlight: el elemento 'FindAncestor, AncestorType' aún no se ha implementado en Silverlight ... No estoy seguro de si hay otro método, además de usar static recursos.

+0

Si no funciona para usted, agregue un pequeño ejemplo de la estructura del objeto Tables [Items]/Tables [Names] de Tablas que está intentando vincular, y veré si puede crear un ejemplo usando eso ... – Claus

+0

También asegúrese de que su tipo de antecesor sea un tipo de 'Ventana' y no un tipo de' UserControl' ya que la propiedad 'DataContext' presentará' null' – Kitson88

0

Este es el comportamiento esperado en realidad: el DataContex t para DataGridCell es la flecha completa.

por lo que tienen 3 soluciones: cualquiera de agregar la unión en el código detrás de la siguiente manera:

en el constructor de cada columna:

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

(usted tiene que encontrar una manera de conseguir la "thisColumnIndex "Por lo que a mí respecta, agrego las columnas inmediatamente después de crearlas, si simplemente coloco" dataGridOwner.Columns.Count "allí).

o ...

se puede encontrar una manera de conseguir el DataContext que desee en cada celda (intentado eso, pero ya que se rompe mal cuando la columna/fila de virtualización está encendido)

o ...

echar un vistazo allí :

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

personalmente encuentro el primero que ser el mejor para mi propósito (ya que añado mis columnas en el código detrás de todos modos), pero esto es realmente hasta que al final ...


En lo que se refiere a columnHeaders (y sólo columnsHeaders, no filas), también puede explorar la forma "DataTemplate":

Conjunto de la cabecera de las columnas a la propia columna (de esa manera se establece la columna como DataContext para el encabezado) y usar un DataTemplate.

por ejemplo:

en cada clase columna:

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; 

y en su xaml de dataGrid, algo así como:

<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> 

por supuesto, mi clase "MyDataGridColumnHeader" contiene definiciones para todos las propiedades a las que se hace referencia aquí.

Espero que esto ayude.

Cuestiones relacionadas