2011-09-13 8 views
7

Estoy intentando crear una cuadrícula programáticamente y anexar un control personalizado como elemento secundario a la cuadrícula como la fila 0 columna 0 de una matriz de 2x2. Para complicar más las cosas, estoy usando el patrón de diseño de MVVM. Aquí está algo de código para ayudar a todos a la idea:Crear tabla de forma programada con elemento personalizado

App.xaml.cs

base.OnStartup(e); 
var viewModel = new MainWindowViewModel(); 
var mainWindow = new MainWindow(); 
mainWindow.GridWindows = viewModel.Window.GridWindows; 

MainWindowViewModel - método devuelve el GridWindows.

private Grid CreateGrid() 
    { 
     Grid grid = new Grid(); 

     // Create column definitions. 
     ColumnDefinition columnDefinition1 = new ColumnDefinition(); 
     ColumnDefinition columnDefinition2 = new ColumnDefinition(); 
     columnDefinition1.Width = new GridLength(640); 
     columnDefinition2.Width = new GridLength(640); 

     // Create row definitions. 
     RowDefinition rowDefinition1 = new RowDefinition(); 
     RowDefinition rowDefinition2 = new RowDefinition(); 
     rowDefinition1.Height = new GridLength(340); 
     rowDefinition2.Height = new GridLength(340); 

     // Attached definitions to grid. 
     grid.ColumnDefinitions.Add(columnDefinition1); 
     grid.ColumnDefinitions.Add(columnDefinition2); 
     grid.RowDefinitions.Add(rowDefinition1); 
     grid.RowDefinitions.Add(rowDefinition2); 

     // Create preview window. 
     Border border = new Border(); 
     border.BorderThickness = new Thickness(20); 
     border.Padding = new Thickness(8); 
     border.SetResourceReference(Control.BackgroundProperty, "PreviewWindow"); 

     MediaRTSPElement previewElement = new MediaRTSPElement(); 
     previewElement.Name = "RTSPStreamPlayer"; 
     previewElement.Stretch = Stretch.UniformToFill; 
     previewElement.Source = "rtsp://192.100.100.22/media/video1"; 
     previewElement.VideoRenderer = VideoRendererType.EnhancedVideoRenderer; 
     previewElement.LoadedBehavior = WPFEVR.DirectShow.Players.MediaState.Play; 
     previewElement.SpeedRatio = 0.5; 

     //border.Child = previewElement; 

     // Add preview window. 
     for (int i = 0; i < 4; i++) 
     { 
      grid.Children.Add(previewElement as UIElement); 
      Grid.SetColumn(previewElement, i); 
      Grid.SetRow(previewElement, i); 
      break; 
     } 

     return grid; 
    } 

Y el marcado XAML que la red debe asignar a

<Grid x:Name="GridWindows"></Grid> 

El problema es mi control personalizado no aparece en el diseño de la red, aquí está el código XAML que lo hace sin código -detrás, y esto funciona:

 <Grid x:Name="GridWindows"> 
      <!--<Grid.ColumnDefinitions> 
       <ColumnDefinition Width="640" /> 
       <ColumnDefinition Width="640" /> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="340" /> 
       <RowDefinition Height="340" /> 
      </Grid.RowDefinitions> 
      <Border BorderThickness="20" Padding="8" Background="{DynamicResource ResourceKey=PreviewWindow}" Grid.Row="0" Grid.Column="0"> 
       <evr:MediaRTSPElement x:Name="RTSPStreamPlayer" 
           Stretch="UniformToFill" 
           VideoRenderer="EnhancedVideoRenderer" 
           LoadedBehavior="Play" 
           Source="rtsp://192.100.100.22/media/video1" 
           SpeedRatio="0.5" /> 
      </Border> 
      <Border BorderThickness="20" Padding="8" Background="{DynamicResource ResourceKey=PreviewWindow}" Grid.Row="0" Grid.Column="1"> 
       <evr:MediaRTSPElement x:Name="RTSPStreamPlayer2" 
           Stretch="UniformToFill" 
           VideoRenderer="EnhancedVideoRenderer" 
           LoadedBehavior="Play" 
           Source="rtsp://192.100.100.78/media/video1" 
           SpeedRatio="0.5" /> 
      </Border> 
      <Border BorderThickness="20" Padding="8" Background="{DynamicResource ResourceKey=PreviewWindow}" Grid.Row="1" Grid.Column="0"> 
       <evr:MediaRTSPElement x:Name="RTSPStreamPlayer3" 
           Stretch="UniformToFill" 
           VideoRenderer="EnhancedVideoRenderer" 
           LoadedBehavior="Play" 
           Source="rtsp://192.100.100.78/media/video1" 
           SpeedRatio="0.5" /> 
      </Border> 
      <Border BorderThickness="20" Padding="8" Background="{DynamicResource ResourceKey=PreviewWindow}" Grid.Row="1" Grid.Column="1"> 
       <evr:MediaRTSPElement x:Name="RTSPStreamPlayer4" 
           Stretch="UniformToFill" 
           VideoRenderer="EnhancedVideoRenderer" 
           LoadedBehavior="Play" 
           Source="rtsp://192.100.100.22/media/video1" 
           SpeedRatio="0.5" /> 
      </Border>--> 
     </Grid> 

¿Alguna idea de por qué el código programático no funciona?

+0

¿Cómo se ¿estás agregando cuadrícula recién creada a tu vista? –

+0

El diseño estándar de mvvm llama al constructor MainWindowViewModel para obtener las propiedades apropiadas, la propiedad GridWindows almacena la cuadrícula devuelta del método anterior - window = new Models.MainWindow {Layout = 1, GridWindows = CreateGrid()}; – bl4kh4k

+0

Parece que hay algunas cosas malas con su código. En MVVM, no debería crear controles de interfaz de usuario en ViewModel. ¿Cuál fue el problema con la forma en que la tenía, definiendo la grilla en el xaml? – kevev22

Respuesta

7

si está creando Grid en el xaml no puede establecerlo más tarde en el código. Grid (instancia) ya está en visualtree. La sobreescritura de la variable no tendrá ningún efecto. Debe establecer su Grid como contenido del control definido xaml. Supongo que su código es el siguiente:

Código:

this.GridWindows = createdGrid; 

Xaml:

<Grid x:Name="GridWindows"></Grid> 

En código que debe tener algo como esto:

this.GridWindows.Children.Add(createdGrid); 
Cuestiones relacionadas