Consuming C# component from C++/CX and C# - c#

I have created a simple control SimpleControl.xaml in C++/CX defined as:
<UserControl .. > // Attributes omitted for reading simplicity
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image x:Name="PersonaPicture" ... />
<Border x:Name="PhotoTextBackdrop" ... />
<TextBlock x:Name="PersonaName" .../>
</Grid>
</UserControl>
Then this control is used in the following manner in a file “foo.xaml” that uses C++/CX as a code behind. SuperPanel inherits from Windows.UI.Xaml.Controls.Panel and is defined in the TastyLib component (consumed by this C++/CX component). The 'fruity' namespace points to TastyLib. The TastyLib component is coded in C#:
</fruity:SuperPanel>
<local:SimpleControl x:Name="gPerson1" Grid.Row="0" Grid.Column="0" />
<Rectangle Fill="SaddleBrown" Height="50" Width="50" Grid.Row="1" Grid.Column="0" />
<UserControl Grid.Row="2" Grid.Column="0" />
</fruity:SuperPanel>
Setting a breakpoint and looking at the watch , I observed the following to be the children of the panel:
child[0] was Windows.UI.Xaml.UIElement, child[1] was
Windows.UI.Xaml.Shapes.Rectangle and child[2] was
Windows.UI.Xaml.Controls.UserControl
Now, in the watch I was expecting the first child to be a SimpleControl, but instead it is a UIElement, which is surprising to me. Where did that come from? Why is it showing an ancestor of SimpleControl as child[0] while it can still recognize a UserControl as child[2] ?
I recreated another SimpleControl in a C# component that uses TastyLib (So this SimpleControl was also written in C# and did not use C++/CX), and put that control within another SuperPanel, exactly like the first case (but all in C# this time). On setting the same breakpoint and viewing in the watch window I saw child[0] to be what I was expecting - a SimpleControl. In this case:
child[0] was FooProject.SimpleControl, child[1] was Windows.UI.Xaml.Shapes.Rectangle and child[2] was Windows.UI.Xaml.Controls.UserControl
What could be the root cause of this dichotomy? Shouldn’t a control written in C++/CX behave the exact way as a control written in C# (when consuming the same component written in C#) ? I’m guessing that it’s something to do with component interoperability. Has anyone faced a similar problem?
Any advice would be appreciated.
Many thanks.

From the research I've done, the issue is that a winRT boundary is crossed in the case of the control written in C++/CX so when the CLR asks for the type, the object returns back Windows.UI.Xaml.UIElement from its GetRuntimeClassName implementation (why?).
In case of control developed using C#, no winRT boundry is crossed and a .NET object is speaking to another .NET object and hence the type is known.

Related

C# wpf web control

is any way to open a web browser(visible?) in specific browser and do action like clic button, search etc. i try
WebBrowser web = new WebBrowser();
web.Navigate(new Uri("https://www.google.com/"));
but i didnt see it. I too know i can do something like that
System.Diagnostics.Process.Start("chrome.exe","http://www.google.com");
but how then make action there control it? Or the only way is open browse in wpf and show it on some king of window.
The best place to actually start learning how to utilize the different Class Controls at our disposal from the .NET environment is reading their documentation!
WebBrowserClass
They show a relative simple example of how to achieve what you want, with the creation of the webbrowser in XAML. In this XAML, they define a TextBox so you can introduce your absolute path, but also a button to perform the search when you click on it.
<Grid x:Name="MainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBox x:Name="addressTextBox" Width="200" />
<Button Click="Button_Click">Go</Button>
</StackPanel>
<WebBrowser Grid.Row="1" x:Name="myWebBrowser" />
</Grid>
I changed the XAML part a bit, so you don't have your WebBrowser with limited Height and instead have it occupied most of the screen real estate.
PS. In all honesty i cannot pinpoint why your code-behind implementation on the WebBrowser is not working though.

WPF Ribbon - Cannot have nested BeginInit calls on the same instance

Everybody,
I am stuck with a wiered issue since yesterday .
I've searched all the forums , blah blah blah.....
No Luck Yet...
I am making a WPF windows Desktop Application using WPF Ribbon Control .
I created and deployed the whole application on my machine
VS2015.
Windows 8.1 64Bit.
All worked perfect.
But When I deployed it on a Windows 7-32Bit Machine.
It started throwing exception at start of the application. I've put try catch around InitializeComponents(); It throws Error
here is my simplified code,
<Grid>
<Grid.Resources>
<BitmapImage x:Key="PasteImageResource" UriSource="/Images/paste.png" />
<BitmapImage x:Key="AddImageResource" UriSource="/Images/add.png" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<DockPanel x:Name="UiPanel" ScrollViewer.VerticalScrollBarVisibility="Visible" Grid.Row="1" />
<Ribbon x:Name="MainRibbon" RenderTransformOrigin="0.9,0.797" >
</Ribbon>
</Grid>
The problem i found is due to Ribbon Control. As soon as i remove the line (i.e)Ribbon TAg
The error goes away. I've tried to debug and found that the inner exception is saying that
Cannot have nested BeginInit calls on the same instance
Looking for help ..........

Pivot overlapping other elements in WP 8.1 Universal app (and automatically changing margin)

The following XAML shows the content of a Windows Phone 8.1 Universal app page. The idea is to have a bar on top of a pivot. But the pivot is overlapping the bar whereas the sample grid in blue is working as expected.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Background="{StaticResource PhoneAccentBrush}" Height="50" />
<Pivot Grid.Row="1" Background="Green" Width="200" HorizontalAlignment="Left" />
<Grid Grid.Row="1" Background="Blue" Width="200" HorizontalAlignment="Right" />
</Grid>
The resulting Page looks like this:
Where is this "negative margin" coming from?
How can it be avoided?
BTW: Just setting a margin is not a solution as it introduces other problems, for example a jumping GUI when using a SemanticZoom control, I need to know the root cause of the problem to solve it...
Info: It seems that the Windows Phone Pivot automatically changes the margin depending on the current screen settings (status bar shown/hidden). So if your app changes the state of the status bar in some circumstances you will end up having a jumping/changing pivot control.
I've found a solution and created a simple attached property for the Pivot control.
The attached property can be used this way:
<Pivot controls:PivotExtensions.DisableAutoMargin="True">
<PivotItem Header="A">
...
</PivotItem>
<PivotItem Header="B">
...
</PivotItem>
</Pivot>
The class with the attached property can be found here:
http://mytoolkit.codeplex.com/SourceControl/latest#MyToolkit.Extended.WinRT/Controls/PivotExtensions.cs
Downside: You cannot override the template anymore as the attached property changes the template already...
Overriding the control template doesn't seem to work; there is some code in the control that's setting the margin after construction. Also setting the Margin on the offending grid on the Loaded event doesn't work either, the negative margin code runs after that.
The only way I found to make the odd behavior go away was to ask your UI to overlap the status bar:
ApplicationView.GetForCurrentView()
.SetDesiredBoundsMode(ApplicationViewBoundsMode.UseCoreWindow);
Then the Pivot control figures that it doesn't need to try and cover the status bar. Note that you'll now have to give room in your page layout to prevent overlap with the status bar.

Control like debug Object list in WPF

I want to create a WPF control which looks like control which appears while we debug .NET code. I.e. control like the window which shows all the property/value and have top and bottom arrow, clicking on which list scrolls up/down. (I am looking for control which have Scroll bar in this style).
To be more specific, I want to make a control like a Panel in which I can display controls/text and which have sroll button in middle like it appears in debug window as shown in Image link.
Link is having sample of control I am trying to make.
http://www.use.com/supersize.pl?set=11a2085f136b99d6869c
Any help will be appreciated.
It sounds like you want to use the WPF Visualizer that comes with Visual Studio. You can access it in debug mode once execution has hit a break point. It displays every property and value for every item in the visual tree. You can find out more from the How to: Use the WPF Tree Visualizer page on MSDN.
The control you wanted probably like this
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="*"/>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<RepeatButton>Up</RepeatButton>
<ScrollViewer Grid.Row="1" x:Name="sv" VerticalScrollBarVisibility="Hidden">
<Rectangle Height="700" Fill="Black"/>
</ScrollViewer>
<RepeatButton Grid.Row="2">Down</RepeatButton>
</Grid>
also you should control scrollview in codebehind via click eventhandler of RepeatButton.

WPF Design question

Lets say i am developing a chat, first you come to a login window and when your logged in i want to use the same window but chaning the control :P how would be the best way to desight this?
is there any good way to implement this what root element should i use?
Thanks a lot!!
Take a look at Josh Smith's article in MSDN magazine (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx). He describes an interesting method where you have a content presenter on your main window use data templates to switch out what the window is showing.
If you want to do this all within the same window, you could use a Grid as the root element and host a login element (possibly another grid for layout) and the chat window. These elements would stack on top of one another, depending upon the order in which you declare them. To hide the chat element initially, set its Visibility to Collapsed
You could then have the login element's Visibility set to Collapsed when the user submits their login details, and have the chat element's Visibility set to Visible.
I did something similar once and it worked well for me.
Hope that helps.
EDIT I knocked this together in Kaxaml for you to play with (and because I like playing with XAML):
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Border x:Name="_loginForm" BorderBrush="#888" BorderThickness="3" CornerRadius="5"
HorizontalAlignment="Center" VerticalAlignment="Center" Padding="10" Visibility="Visible">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" Height="30">Welcome to chat</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0">User Name</TextBlock>
<TextBox Grid.Row="1" Grid.Column="1" x:Name="_userName" />
<TextBlock Grid.Row="2" Grid.Column="0">Password</TextBlock>
<TextBox Grid.Row="2" Grid.Column="1" x:Name="_password"></TextBox>
<Button Grid.Row="3" Grid.Column="1">Log In</Button>
</Grid>
</Border>
<DockPanel x:Name="_chatForm" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" LastChildFill="True" Visibility="Collapsed">
<DockPanel DockPanel.Dock="Bottom" LastChildFill="True" Height="70">
<Button DockPanel.Dock="Right" Width="70">_Send</Button>
<TextBox x:Name="_input" HorizontalAlignment="Stretch">Hello world</TextBox>
</DockPanel>
<ListBox x:Name="_messageHistory" />
</DockPanel>
</Grid>
</Page>
Initially the element _loginForm is visible. You'd attach a handler for the Log In button's Click event that would hide it, and show the _chatForm instead.
This example shows usage of several layout controls -- the Grid, DockPanel and StackPanel.
Alternatively, you can use a StackPanel for your layout. As a simple example, you can have 2 elements in your panel; a custom login control as well as the chat 'display' control. After successfully logging in, remove the custom login control from your stack so only the chat is visible.
It's WPF! Animate them in and out of view...you can do that now. There's a collaborative project on Google Code called Witty (a desktop Twitter client written in WPF), and they do something really cool that you might want to borrow from. Come to think of it, there's another WPF Twitter client (blu) that does similar animations that you might want to look at.
In Witty, the Settings dialog is a normal window, but when you switch between the tabs, a storyboard slides the part of the window you requested into view. I haven't debugged the app at this level, but I'm assuming that they have a horizontal StackPanel populated with containers that are fixed to the height and width of the dialog, and they slide them in and out with a storyboard.
Take a look at both of these apps for ideas. You may want to do something similar, but being that this is a WPF app, the sky is really the limit.
Witty
blu
There are already some answers here on, how to swap two elements at the view level. This post offers a way to more fundamentally create a modular application design with interchangeable views.
You could take a look at the Composite Application Library. It is a small library (developed by Microsoft) that among other things aid in making your application more modular. With this you can define regions of your GUI, that can have interchangeable views.
In your containing xaml import the CAL namespace and use RegionManager to define a region:
<Window ...
xmlns:cal="http://www.codeplex.com/CompositeWPF"
...>
...
<ItemsControl cal:RegionManager.RegionName="MyRegion" />
...
Then you can swap views in this region, preferably in a module:
_regionManager.Regions["MyRegion"].Add(new LoginView());
...swap...
_regionManager.Regions["MyRegion"].Add(new ChatView());
This is of course just an outline of what you can do. In order to implement this solution, you will have to look further in to CAL. It has great documentation and lots of examples to learn from.
I think a more intuitive solution is to use a Frame control as the base control of your window - and to use the NavigateService to change the source of the Frame to different Page controls (which could be defined in separate assemblies, or in your same project as different XAML files).
Your Window:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Frame Source="LogonPage.xaml" NavigationUIVisibility="Hidden" />
</Window>
And your separate LogonPage:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Logon">
<!-- Your content of the page goes here... -->
</Page>

Categories