【问题标题】:Programmatically Create Grid with Custom Element以编程方式使用自定义元素创建网格
【发布时间】:2011-09-14 01:00:35
【问题描述】:

我正在尝试以编程方式创建一个网格,并将一个自定义控件作为子项附加到网格中,作为 2x2 矩阵中的第 0 行第 0 列。为了让事情变得更棘手,我使用了 MVVM 设计模式。这里有一些代码可以帮助大家理解:

App.xaml.cs

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

MainWindowViewModel - 方法返回 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;
    }

以及网格应分配给的 XAML 标记

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

问题是我的自定义控件没有出现在网格布局中,这是没有代码隐藏的 xaml 代码,这确实有效:

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

关于为什么程序化代码不起作用的任何想法?

【问题讨论】:

  • 如何将新创建的网格添加到视图中?
  • 标准 mvvm 设计调用 MainWindowViewModel 构造函数来拉入适当的属性,GridWindows 属性存储从上述方法返回的网格 - window = new Models.MainWindow { Layout = 1, GridWindows = CreateGrid() };
  • 您的代码似乎有很多问题。在 MVVM 中,您不应该在 ViewModel 中创建 UI 控件。你的方式有什么问题 - 在 xaml 中定义网格?
  • 我认为那是我搞砸的地方,是 MVVM,但我不是通过 xaml 来做的,因为网格可以根据 4 个按钮来改变它的布局,并且基本上每个网格都会拉入一个视频流位置。
  • 似乎是我的自定义控件,我从视图模型中删除了 ui 方法,你的权利它不属于那里......但我有它可以显示元素,我的自定义控件似乎是罪魁祸首......但奇怪的是它在 xaml 中工作而不是在代码后面。有什么想法吗?

标签: c# wpf xaml


【解决方案1】:

如果您在 xaml 中创建 Grid,则以后无法在代码中设置它。网格(实例)已经在 visualtree 中。覆盖变量不会产生任何影响。您应该将 Grid 设置为 xaml 定义的控件的内容。我猜你的代码是这样的:

代码:

this.GridWindows = createdGrid;

Xaml:

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

在代码中你应该有这样的东西:

this.GridWindows.Children.Add(createdGrid);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 2020-02-08
    相关资源
    最近更新 更多