【问题标题】:Hosting CaptureElement with WindowsXamlHost Overlay使用 WindowsXamlHost 覆盖托管 CaptureElement
【发布时间】:2020-04-12 10:43:31
【问题描述】:

我试图在我的 WPF .NET Core 3.1 应用程序中将Grid 覆盖在WindowsXamlHost 托管的CaptureElement (相机源)之上,但CaptureElement 始终位于任何其他控件之上。

不能在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));
    }
}

【问题讨论】:

    标签: c# wpf .net-core uwp xaml-islands


    【解决方案1】:

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

    没有。就像WindowsFormsHost 中的 Windows 窗体控件一样,WindowsXamlHost 托管在始终绘制在 WPF 元素之上的单独 HWND 中。

    来自docs

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

    有一个类似的问题,有一些答案here

    【讨论】:

      【解决方案2】:

      当我尝试使用 XAML Islands 在我的 WPF 应用程序中托管 CaptureElement 时遇到了同样的问题。正如 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-09-14
        • 2017-09-20
        • 1970-01-01
        • 2013-12-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-26
        • 1970-01-01
        相关资源
        最近更新 更多