3

我试图覆盖在我的 WPF .NET Core 3.1 应用程序中托管的 (Camera Feed)Grid之上,但始终保持在任何其他控件之上。CaptureElementWindowsXamlHostCaptureElement

不能在上面叠加一个网格WindowsXamlHost/CaptureElement吗?

Î 创建了一个示例应用程序https://github.com/ValonK/SampleWPFXamlHost。我需要CaptureElement并且还没有找到任何东西来捕捉相机馈送并在它们上方放置一些叠加层。

Xaml 代码

<Window x:Class="SampleWPFXamlHost.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:SampleWPFXamlHost"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid Height="200"
              Width="200"
              Background="Red"/>
        <ContentControl HorizontalContentAlignment="Stretch"
                        VerticalContentAlignment="Stretch"
                        Content="{Binding XamlHostCaptureElement}"/>


    </Grid>
</Window>

视图模型

public class MainViewModel : PropertyChangedAware
{
    public MainViewModel()
    {
        GetUwpCaptureElement();
    }

    private MediaCapture _mediaCapture;

    public MediaCapture MediaCapture {
        get {
            if (_mediaCapture == null)
                _mediaCapture = new MediaCapture();
            return _mediaCapture;
        }
        set {
            _mediaCapture = value;
            OnPropertyChanged(nameof(MediaCapture));
        }
    }


    public CaptureElement CaptureElement { get; set; }

    public WindowsXamlHost XamlHostCaptureElement { get; set; }

    /// <summary>
    /// Create / Host UWP CaptureElement
    /// </summary>
    private void GetUwpCaptureElement()
    {
        XamlHostCaptureElement = new WindowsXamlHost
        {
            InitialTypeName = "Windows.UI.Xaml.Controls.CaptureElement"
        };
        XamlHostCaptureElement.ChildChanged += XamlHost_ChildChangedAsync;
    }

    private async void XamlHost_ChildChangedAsync(object sender, EventArgs e)
    {
        var windowsXamlHost = (WindowsXamlHost)sender;

        var captureElement = (CaptureElement)windowsXamlHost.Child;
        CaptureElement = captureElement;
        CaptureElement.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill;

        try
        {
            await StartPreviewAsync();
        }
        catch (Exception)
        {

        }
    }

    private async Task StartPreviewAsync()
    {
        try
        {
            await MediaCapture.InitializeAsync();
        }
        catch (UnauthorizedAccessException ex)
        {
            //_logger.Info($"The app was denied access to the camera \n {ex}");
            return;
        }

        try
        {
            CaptureElement.Source = MediaCapture;
            await MediaCapture.StartPreviewAsync();
        }
        catch (System.IO.FileLoadException ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.ToString());
        }

    }
}

public class PropertyChangedAware : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
4

2 回答 2

1

不能在 WindowsXamlHost/CaptureElement 上覆盖网格吗?

不。就像 a 中的 Windows 窗体控件一样WindowsFormsHost,aWindowsXamlHost托管在一个单独的 HWND 中,该 HWND 始终绘制在 WPF 元素的顶部。

文档

托管的 Windows 窗体控件在单独的 HWND 中绘制,因此它始终绘制在 WPF 元素之上。

有一个类似的问题,这里有一些答案。

于 2019-12-20T12:50:46.597 回答
1

CaptureElement当我尝试使用 XAML Islands 在我的 WPF 应用程序内部托管时,我遇到了同样的问题。正如 mm8 所说,问题是因为 WPF 将在任何 WPF 元素之后绘制 WindowsXamlHost。

但是如果你只是想TextBlock在你的CaptureElement. 只需托管 UWP 用户控件,而不是CaptureElement直接托管。使用 MVVM,您可以将文本从您的 WPF 应用程序传递到您的 UWP 用户控件,它将显示。

例子:

<UserControl
    x:Class="MyUwpApp.MyUserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">

    <Grid>
        <CaptureElement x:Name="captureElement"/>
        <TextBlock Text="{Binding MyText}" Foreground="Yellow" FontSize="64" VerticalAlignment="Bottom" HorizontalAlignment="Left" Margin="15"/>
    </Grid>
</UserControl>
于 2021-04-12T16:07:09.417 回答