WP7/Silverlight: how to disable/remove adctrol from visual tree - silverlight

I am building a app that supports trial and I want to show ads in trials and no ads in paid. Upon investigation I found that the only way to disable the ads for paid version is to remove the adcontrol completely from the visual tree.
Now my question is how do I remove the adcontrol from my visual tree in my code when I detect it is a paid version and not a trial. Can you please help?
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
...
</Grid>
<Grid Grid.Row="1">
...
</Grid>
<Grid Grid.Row="2">
<ad:AdControlx:Name="itemAds" .../>
</Grid>
</Grid>

If you set the Visibility of the control to Visibility.Collapsed it will be removed from the visual tree.
You therefore just need one line of code:
itemAds.Visibility = Visibility.Collapsed;

You don't even need to name the grid:
var parent = itemAds.Parent as Grid;
if (parent != null)
{
parent.Children.Remove(itemAds);
}

Could you name the Grid that is wrapping the AdControl and then call, myGrid.Children.Clear() ?

Related

Appium can't locate collapsed element

I'm trying to access the Type property of the custom prompt dialog from an automation test. So the element for the Type (text box or text block) is collapsed because no one needs to see it, I just need it for logical processing on automation side.
I don't understand why it can't be located despite being available in the tree. or is there another why to get such access?
XAML:
<controls:PromptDialog ...
AutomationProperties.AutomationId="PromptView"
d:DataContext="{d:DesignInstance Type=viewModels:PromptViewModel}">
<Grid Margin="{StaticResource MarginThickness}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="{StaticResource Gutter}" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--Prompt-->
<Grid Grid.Row="0"
Visibility="{Binding IsShowingPrompt, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="4" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="{StaticResource Gutter}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--Image-->
<ContentControl Grid.Row="0"
Grid.Column="0"
Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModels:PromptViewModel}">
<Image Name="Image" />
//displaying image per type
</ContentControl.Resources>
</ContentControl>
<ScrollViewer Grid.Row="0"
Grid.Column="2"
Focusable="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
MaxHeight="400">
<StackPanel>
<TextBlock behaviors:TextBoxHyperlinkBehavior.Text="{Binding Text}"
TextWrapping="Wrap"
Focusable="False"
VerticalAlignment="Center"
HorizontalAlignment="Left"
FontFamily="{Binding Font.Name}"
Foreground="{Binding FontColor}"
AutomationProperties.AutomationId="PrompView_Text" />
<TextBox Visibility="Collapsed"
Text="{Binding Type}"
AutomationProperties.AutomationId="PromptView_Type" />
</StackPanel>
</ScrollViewer>
<!--Commands-->
<UniformGrid Grid.Row="2" Rows="1" HorizontalAlignment="Right">
// buttons
</UniformGrid>
</Grid>
</controls:PromptDialog>
Appium:
public IVisualElement Type => _appiumSession.CreateVisualAppiumElement("PromptView_Type");
Or
public AppiumWebElement Type => _appiumSession.FindElementByAccessibilityId("PromptView_Type");
WPF Snoop:
Error:
OpenQA.Selenium.WebDriverTimeoutException : Timed out after 10 seconds
---- OpenQA.Selenium.WebDriverException : An element could not be located on the page using the given search parameters.
Any pointers are highly appreciated,
thanks
There were several times when I used Snoop and it found more elements/attributes that Appium can access.
That is why now I am using Accessibility Insights for Windows. Of course you can use inspect.exe, but Accessibility Insights for Windows is the recommended from Microsoft. You can also try WinAppDriver UI Recorder that is generating XPaths.
If your element is not present in Accessibility Insights for Windows Appium will not be able to locate it.
According to documentation:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.visibility?view=net-5.0
Collapsed elements are not rendered and NOT in layout.
Why not to use Visibility.Hidden instead, or Visibility.Visible with height of 0px.
I don't know anything about Appium, but the problem could be solve with .net automation api very easily.
// Must find top window of app first or could cause overflow easily.
var topWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.AutomationIdProperty, "Id of top window"));
// Find out your target element if it's in visual tree, whatever it's collapsed or not.
// You can also Find out another element in the middle first to reduce the search work.
var target = topWindow.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.AutomationIdProperty, "PromptView_Type"));
// retrieve the value.
var val = ((ValuePattern)target.GetCurrentPattern(ValuePattern.Pattern)).Current.Value;
You have to add reference to UIAutomationClient.dll and UIAutomationType.dll to make this code work.
Update for .net core app
For .net core(3.0, 3.1, 5.0), there's a huge difference about how an automation peer answer inquiry than .net framework app. Automation peer will not answer inquiry if it's offscreen(control's visibility had been set to collapsed or hidden) unless inquiry was targeting raw view. So we have to force inquiry target to make it works.
var topWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "Id of top window"));
AutomationElement target = null;
var cr = new CacheRequest()
{
TreeFilter = Automation.RawViewCondition,
};
using (cr.Activate())
{
target = topWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "PromptView_Type"));
}

How to add controls dynamically to a UserControl through user's XAML, 4.0

I want to create a user control that contains a Image and a Conainer that will allow the user to add his/her own controls to the user control dynamically in XAML. I am using VS 2010, .NET 4.0
I have created following code.
UserController.xaml
<Grid DockPanel.Dock="bottom">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Height="Auto" Grid.Row="0" Grid.Column="0">
<Image />
</StackPanel>
<Grid>
<ContentControl Content="{Binding Innercontent}" />
</Grid>
</Grid>
ModeViewCode, Innercontent is an DependencyProperty property
public static DependencyProperty InnerContentProperty = DependencyProperty.Register("InnerContent", typeof(UIElement), typeof(Footer))
public UIElement InnerContent
{
get { return (UIElement)GetValue(InnerContentProperty); }
set { SetValue(InnerContentProperty, value); }
}
Created a DataTemplate which consumes the usercontrol.
<users:Footer HorizontalAlignment="Stretch" VerticalAlignment="Bottom">
<users:Footer.InnerContent>
<StackPanel Orientation="Horizontal" x:Name="tst">
<commoncontrols:Button />
</StackPanel>
</users:Footer.InnerContent>
</users:Footer>
when code is complied it gives me following error message.
Error 275 Unknown build error, 'Index (zero based) must be greater than or equal to zero and less than the size of the argument list. Line 2582 Position 23.' at this line (users:Footer.InnerContent).
Got help from following psot Help
Any help will be appreciated.

WPF: Two borders with solid background have a ugly pixel row on top (merging color with parent panel's background)

Below there is shown a simple part of my wpf app where you can see two borders (1. and 2.).
At 3. you can see a lite red line (which is my problem). This line was never (explicitly) defined in xaml code. The red background was only defined in a parental grid and is gleam through at the top of the border element. Below Is my code:
<Window
x:Class="BgColorBug.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="200" Width="200"
WindowStartupLocation="CenterScreen"
>
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="1" Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Border
Grid.Row="0"
Height="4" Background="#1F1F1F" />
<Border
Grid.Row="1"
Background="#777777"
>
<WrapPanel
Orientation="Horizontal"
HorizontalAlignment="Right"
>
<Button Padding="7" Margin="7">Hello</Button>
<Button Padding="7" Margin="7">World</Button>
</WrapPanel>
</Border>
</Grid>
</Grid>
When I define fix row heights (instead of the auto value) then the red line is not showing so I think it's a rendering problem (by the side the border from 1. has a red line too).
While I has written my question I found that article with the solution to my problem.
There must be declared UseLayoutRounding="True" on any grid above the last one (because that value is inherited down).
<Grid Grid.Row="1" Background="Red" UseLayoutRounding="True">
After known the keyword 'LayoutRounding' I found this Article on StackOverflow with a similar problem.
After knowing the issue with LayoutRounding=False I don't know what are the benefits from not using it? Maybee performance?
What is the best practise using that flag? In some Microsoft articles they say to set it true on the root element (which is the main window). But if so then I'm wondering why that flag is not true by default.

show a label always at the bottom of the page in silverlight

In my Silverlight Application , I have a label which contains the copyright information.I want to show the label always at the bottom of the screen in every resolution.
<sdk:Label
Height="28"
x:Name="label1"
Width="422"
Content="Copyright © 2013. All rights reserved." Margin="253,662,252,-41" />
with margin I am only able to show it at bottom on my screen.
How to do it?
You can use Grid with two Rows. One "Stretch" Height="*" and the second adaptable to content Height="Auto". Use HorizontalAlignment for the label :
<Grid x:Name="LayoutRoot" >
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid>
<!-- Main content -->
</Grid>
<!-- Put the label in row 1 : Grid.Row="1"-->
<!-- elastic width :) : HorizontalAlignment="Stretch"-->
<sdk:Label
Grid.Row="1"
Height="28"
x:Name="label1"
HorizontalAlignment="Stretch"
Content="Copyright © 2013. All rights reserved." />
</Grid>

Hub Tiles animation "semi expanded" broken

I have an issue with the Windows Phone toolkit's hub tile.
All my hub tiles disappear when the animation state change to "semi expanded" (The one where half the icon + the text is visible). After a while the will change their animation state to different one and thetext or the right images show up as you expect them to.
It works in the emulator but not on my Lumia 800 and in the XAML preview of VS. Programming for WP 7.5 with VS 2010 on Win7 x64.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,12">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<toolkit:HubTile
Grid.Row="1"
Grid.Column="0"
Margin="12,12,0,0"
Title="Brew 
House"
Source=""
Tap="HubTile_Tap"
Name="BrewHouseTile">
</toolkit:HubTile>
<toolkit:HubTile
Grid.Row="1"
Grid.Column="1"
Margin="12,12,0,0"
Title="Hops"
Source="/BrewingApp;component/Images/icon_hops_big.png"
Tap="HubTile_Tap"
Name="HopsTile" />
<toolkit:HubTile
Grid.Row="2"
Grid.Column="0"
Margin="12,12,0,0"
Title="Convert 
Units"
Tap="HubTile_Tap"
Source="/BrewingApp;component/Images/icon_scales_big.png"
Name="ConvertersTile" />
... more Hub Tiles
</Grid>
</Grid>
This actually a bug in the Windows Phone toolkit. Upon resizing of the Hub Tiles the width and height get calculated again. This calculation uses a Float.TryParse() method that relies on a CultureSetting. However, when not set to EN-US this break. There is an issue on Codeplex with a quickfix:
http://phone.codeplex.com/workitem/10602
This has exactly happened to me.
To resolve the bug:
You need to download the toolkit sources from here: http://phone.codeplex.com/SourceControl/changeset/view/80797#
Modify the HubTileConverters.cs as it´s said in http://phone.codeplex.com/workitem/10602
And then compile. The dll file will be in the Bin ->Debug or Bin->Release depending if you compiled in debug or device mode.
You use this new dll fixed and works perfectly.

Resources