如何访问 WPF 代码隐藏中的 ContentControl DataTemplate 中的对象,或者如何在 xaml 中设置 CefSharp DownloadHandler

How can I access an object that is in a ContentControl DataTemplate in WPF codebehind, or how do I set a CefSharp DownloadHandler in xaml

我在项目中有一个 XAML 文件,我将其抽象为:

    <Grid>
        <ContentControl KeyboardNavigation.IsTabStop="False" Content="{Binding }" Grid.Row="8" Grid.ColumnSpan="5" x:Name="Bob">
            <ContentControl.Resources>
                <DataTemplate x:Key="FooView">
                    <wpf:ChromiumWebBrowser x:Name="CefBroswer"
                    Address="{Binding Path=HTML}">
                </DataTemplate>
                <DataTemplate x:Key="BarView">
                    <TextBox Text="{Binding Path=Bar}"></TextBox>
                </DataTemplate>
            </ContentControl.Resources>

            <ContentControl.Style>
                <Style TargetType="{x:Type ContentControl}">
                    <Setter Property="ContentTemplate" Value="{StaticResource FooView}"/>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsBar}" Value="True">
                            <Setter Property="ContentTemplate" Value="{StaticResource BarView}"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ContentControl.Style>
        </ContentControl>

    </Grid>

此代码的想法是,如果 ViewModel.IsBar 为真,则在文本框中显示 ViewModel.Bar,否则导航至 ViewModel.HTML - 显示 [=43] 背后有商业原因=] 或可编辑的文本框。

我试图让 CefSharp 浏览器在我想要下载文件时以某种方式运行。当我们使用 WebBrowser 时,对 Word 文档的 link 导致 IE 出现并提供一个 Open/Save 框。 CefSharp 不会在没有被告知要做什么的情况下处理这个问题。虽然这提供了更多的功能,但这确实意味着我们已经从能够处理一系列文件退化到能够处理 CefSharp 可以本地显示的内容(即 HTML 和图像)

我已经尝试了一些我在网上找到的代码片段来获取代码隐藏中的 CefBrowser。我能得到的最接近的是 Bob,但我找不到让 FindName 工作的方法——几乎我发现的每个片段都在谈论 ListViewItems,以及我没有的属性。

我正在尝试在代码隐藏中获取对象,以便我可以将 myDownloadHandler 附加到浏览器:

    CefSettings settings = new CefSettings();
    Cef.Initialize(settings);

    CefBrowser.DownloadHandler = myDownloadHandler; //This is what documentation says to use for this
    DataTemplate bob = Bob.FindResource("FooView") as DataTemplate;

我尝试过的另一件事是直接在 xaml 中分配处理程序:

                    <wpf:ChromiumWebBrowser x:Name="CefBroswer"
                    Address="{Binding Path=HTML}"
                    DownloadHandler="{Binding Path=myDownloadHandler}">

这让它感到不安 - 我假设它绑定到处理程序的结果,而不是处理程序本身,这让事情变得混乱

                    <wpf:ChromiumWebBrowser x:Name="CefBroswer"
                    Address="{Binding Path=HTML}"
                    DownloadHandler="MyDownloadHandler">

这也没有用,并且给出了关于从字符串转换的智能感知错误。当然,现在我已经把它放回去尝试复制消息,它没有显示。这与字符串和 IDownloadHandler

之间的转换有关

所以,问题是: 1:有什么办法可以在后面的代码中获取 CefBrowser 吗? 2:有什么方法可以在 xaml 中附加处理程序? 3:有没有我可以采用的更好的方法,不会破坏功能?

添加 Loaded 事件处理程序:

<wpf:ChromiumWebBrowser Loaded="BrowserLoaded" ...>

sender 转换为 ChromiumWebBrowser 类型并分配 DownloadHandler:

private void BrowserLoaded(object sender, RoutedEventArgs e)
{
    var browser = sender as ChromiumWebBrowser;
    browser.DownloadHandler = myDownloadHandler;
}