Overlay over WebBrowser control - c#

I have a TabControl (using InfragisticTabControl) where each TabItem contains a WebBrowser control where I can display a URL like www.google.com or any xbap UI.
Below is the TabItem Code:
<Grid>
<WebBrowser x:Name="myBrowser"
webHelper:WebBrowserHelper.BrowserSource="{Binding XBAP_URI}"
Height="Auto"/>
<Grid Name="MyOverlayGrid" Background="LightGray" Opacity="0.5"
Visibility="{Binding Path=IsEnabled, Converter={StaticResource BoolToVisible2}, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type igDock:ContentPane}}}">
<TextBlock Text="User does not have permissions for this application" FontSize="24"/>
</Grid>
</Grid>
I verified using snoop that Visibility binding is correctly getting populated, but I don't see MyOverlayGrid on myBrowser control. I even tried updating Panel.ZIndex for MyOverlayGrid, no help.
Only thing that worked is to set myBrowser visibility to hidden (i used snoop) and then i could see MyOverlayGrid.
Can anyone tell me if I am doing something incorrect or missing something obvious? This works fine for a contentcontrol, may be its not possible for a WebBrowser control since the its starts new applictaion (InternetExplorer.exe or PresentationHost.exe) in the tab control?
Thanks,
RDV

Can anyone tell me if I am doing something incorrect or missing something obvious?
The latter am I afraid. The WebBrowser control is hosted in a separate HWND that is always drawn on top of the WPF elements as stated in the documentation on MSDN: https://msdn.microsoft.com/en-us/library/ms744952(v=vs.110).aspx.
There is nothing much you can do about this besides applying a workaround like for example putting your Grid in a Popup.
You may want to consider using some other third-party WebBrowser control such as for example Chromium.

Related

How to disable opening WPF popup

I have a Popup and a ToggleButton. I set a binding like this:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}" />
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
As you see, I bound the toggle button's content to MyData.Title and the popup's content to MyData.Details.
Now I had the criteria MyData.ShowDetails. If it is true the popup can open and if it is false the popup should not be opened.
How can I set a binding to achieve this?
I tested these bindings on the Popup but no one works:
Visibility="{Binding MyData.ShowDetails, Converter={StaticResource BooleanToVisibilityConverter}}"
IsEnable="{Binding MyData.ShowDetails}"
You could put a panel (Grid ) on top of all the content in your window.
That needs to have a background set but it can be low opacity if you still want to see the window content.
Make that visible only when the popup is shown and collapse otherwise.
Make sure you set focus to your popup when it's shown.
.
Bear in mind.
Popups are separate windows.
They are intended to be shown briefly and have a number of potential drawbacks if you show them for longer periods. EG other applications can appear under them and they don't move with their "parent" window/control.
You might find a modal window is easier and suits better, depending on your exact requirements.
Just instantiate a window and use
PopupWindow newWindow = new PopupWindow();
newWindow.ShowDialog();
Where PopupWindow is just any old window styled to look like you want the popup.
This will guarantee the user can't somehow interact with any other window in your app.
.
Another possibility is to show your "popup" content in a grid which appears on top of everything inside your main window.
That's how editing data works in this:
https://gallery.technet.microsoft.com/scriptcenter/WPF-Entity-Framework-MVVM-78cdc204
The plus or minus of that approach is that it's in the one window.
--- Brian Kress ---
I found a special answer in my case. Instead of disabling Popup, I should disable the ToggleButton:
<ToggleButton x:Name="myToggle" Content="{Binding MyData.Title}"
IsEnabled="{Binding MyData.ShowDetails}"/>
<Popup IsOpen="{Binding IsChecked, ElementName=myToggle}" >
<TextBlock Text="{Binding MyData.Details}" />
</Popup>
It works perfect!
Note: This is not a general answer for Popup. Welcome to anyone who has an answer.

Dragablz TabablzControl Visibility property not working

I'm using dragablz:TabablzControl in a project of mine and I have the need of hide/show some tabs dinamically.
The fact is the control is not respecting the property Visibility of the TabItem.
I've tried with and without binding, like this:
<dragablz:TabablzControl Grid.Row="2" BorderThickness="0" FixedHeaderCount="20">
<TabItem Header="Additional Info" Visibility="{Binding ShowAdditionalInfoTab, Converter={StaticResource BooleanToVisibilityConverter}}">
<controls:AdditionalInfoControl />
</TabItem>
<TabItem Header="Additional Info" Visibility="Collapsed">
<controls:AdditionalInfoControl />
</TabItem>
</dragablz:TabablzControl>
But none is working. Change the "FixedHeaderCount" does not affect the result.
The tab remains always visible.
Is there any other way that I can achieve the result I need?
I've received a response from the development team, and I'm leaving it here for anyone who has the same problem.
Yeah, obviously there’s since changes to the standard tab control to support all of the extra features, and currently that’s not supported. You’d have to temporarily remove your hidden item from the source.

Attach attribute to Scrollviewer of Textbox

I need to sync two scroll viewers in WPF, one of which is part of the TextBox item.
I intend on using the method described on CodeProject here:
However, this requires that I can attach attributes to both scrollviewers. One of the scrollviewers is the scrollviewer that comes as part of a textbox.
Code at the moment:
<ScrollViewer Core:ScrollSynchronizer.VerticalScrollGroup="V1">
<UIComponents:LineNumberBox
x:Name="LineBox"
VisibleLines="{Binding ElementName=CodeBox, Path=(UIComponents:VisibleLinesBinder.VisibleLines)}"
Padding="2,10,2,0"
FontSize="14"
Grid.Column="0"
/>
</ScrollViewer>
<UIComponents:SourceCodeBox
x:Name="CodeBox"
Padding="10"
FontSize="14"
Grid.Column="1"
UIComponents:VisibleLinesBinder.ObserveVisibleLines="True"
Core:ScrollSynchronizer.VerticalScrollGroup="V1"
/>
A UIComponents:SourceCodeBox is just a wrapper around a normal WPF Textbox.
Obviously the Core:ScrollSynchronizer.VerticalScrollGroup="V1" on the SourceCodeBox doesnt work? So how would I attach that attribute to the ScrollViewer within it? C# or XAML methods are both fine.
In case it makes any difference this is part of a User Control I am developing.
put the attatched behavior in a style like this:
<UIComponents:SourceCodeBox
x:Name="CodeBox"
Padding="10"
FontSize="14"
Grid.Column="1"
UIComponents:VisibleLinesBinder.ObserveVisibleLines="True"
Core:ScrollSynchronizer.VerticalScrollGroup="V1">
<UIComponents:SourceCodeBox.Resources>
<Style TargetType="ScrollViewer">
<Setter Property="Core:ScrollSynchronizer.VerticalScrollGroup" Value="V1"/>
</Style>
</UIComponents:SourceCodeBox.Resources>
</UIComponents:SourceCodeBox>

Resources and ContentControl templates

When setting a contentcontrols template to xaml in code behind I cant access a static resource contained in the parent xaml.
I have a contentcontrol as follows:
<ContentControl x:Name="ccMaterial">
<ContentControl.Resources>
<x:Array x:Key="BondListKey" Type="sys:Int32"
xmlns:sys="clr-namespace:System;assembly=mscorlib" />
</ContentControl.Resources>
</ContentControl>
then in codebehind I am setting the template as follows:
string template = "<ControlTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>" +
"<ComboBox Grid.Column=\"1\" Grid.Row=\"0\" ItemsSource=\"{Binding Source={StaticResource BondListKey}}\" />" +
"</ControlTemplate>";
ccMaterial.Template = (ControlTemplate)XamlReader.Parse(template);
The problem is that when i try to run this I get the exception saying that the resource "BondListKey" cannot be found. Can anyone explain why?
Please let me know if you need anymore information.
In response to Johns comments :
I have a tab item and I want to be able to display different controls within that tab based on a user selection somewhere else on the form. As an example if the user selected a car I would like to be able to change the control template to include a textbox for engine size, fuel type etc, if the user selected an orange I would like a control template that included variety and sweetness. I suspect I could get this functionality by drawing all possible controls on the tab, then altering the visible/enabled state of the relvant controls based on a datatrigger, but this would potentially involve a LOT of filtered controls ( as there may be many user selection types ). What I ideally want to be able to do is have the desired control template supplied as a string, parsed and assigned to the template of the control, thus modifying its contents at runtime.
Please let me know if that didnt make sense or you need anythign clarifying :)
StaticResource is a static lookup that is executed once at load time. If the target resource is not found at that time, you get an error, which is you're seeing now. Because you're loading the template in the context of the XamlReader the resources in your XAML aren't available. In most cases the fix is to use DynamicResource instead to provide a default value that gets updated when the resource becomes available, but Binding Source is not a DependencyProperty and so can't use Dynamic.
Rather than using a XamlReader, you can just declare your XAML in XAML and take advantage of the context that's available there:
<ContentControl x:Name="ccMaterial">
<ContentControl.Resources>
<x:Array x:Key="BondListKey" Type="sys:Int32"
xmlns:sys="clr-namespace:System;assembly=mscorlib" />
<ControlTemplate x:Key="MyTemplate">
<ComboBox Grid.Column="1" Grid.Row="0" ItemsSource="{Binding Source={StaticResource BondListKey}}" />
</ControlTemplate>
</ContentControl.Resources>
</ContentControl>
You can then still do the loading from code with:
ccMaterial.Template = ccMaterial.FindResource("MyTemplate") as ControlTemplate;

Dynamically Adding child controls to a silverlight textbox

Please forgive this stupid question. (I'm originally an ASP.NET programmer.)
I'm trying to add a telerik context menu to a textbox control in the code behind.
Adding it in the xaml is very easy (this works)
<TextBox AcceptsReturn="True" Text="{Binding Mode=TwoWay, Path=Description}" TextWrapping="Wrap" x:Name="txtIssues" Width="280" Height="100" VerticalScrollBarVisibility="Auto">
<telerikNavigation:RadContextMenu.ContextMenu>
<telerikNavigation:RadContextMenu x:Name="contextMenu"
ItemClick="ContextMenuClick">
<telerikNavigation:RadMenuItem Header="Set Vista as Background" />
<telerikNavigation:RadMenuItem Header="Set Beach as Background" />
<telerikNavigation:RadMenuItem Header="Set Forest as Background" />
</telerikNavigation:RadContextMenu>
</telerikNavigation:RadContextMenu.ContextMenu>
</TextBox>
However I would like to completely add the the control from c# code and I can't find a why to add a control to a textbox. I've been looking for something like "txtIssues.Children.Add" but there doesn't seem to be an option.
First its best you understand that you are not adding a control to the TextBox. The RadContextMenu.ContextMenu is not a control it is an attached property.
Funnily enough the Telerik documentation describes adding a context menu to a textbox in C#. See Working with the RadContextMenu. Sometimes "RTM" is actually good advice.

Categories

Resources