Make a button "public" in xaml and c# - c#

I am building a mobile app using the Xamarin platform. In the solution, there is a core project and then the platform specific projects, in this case, .ios and .android. In my core project I have a XAML layout, with a button element.
My_App.Core.HomePage.xaml
<Button x:Name="LoginIcon"
Image="key.png"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand"
Grid.Row="9" Grid.Column="3" Grid.ColumnSpan="3" />
I have some platform specific logic in those projects, the result of this I would like to alter the source of these buttons. e.g.
My_App.ios.customfile.cs:
My_App.HomePage.LoginIcon.Source = ImageSource.FromFile("bluetoothg.png");
of course, as the button is defined in XAML, LoginIcon isn't visible from this file, how can I make this XAML element public, so I can reference it from other projects in the solution which reference the core files?

The x:FieldModifier namespace attribute specifies the access level for generated fields for named XAML elements.

Create a property on your page and return the button:
public Button PubLoginIcon{ get{ return LoginIcon; } }
BUT, I must say something is wrongly designed if you must access the controls on another page, a better approach is to have the functionality in the page as a public function, in this case you have no need to access the controls.

Related

How to fetch a string resource in a class library

I'm working on a class library which contains several .resw resource files and pages. The question is, how to fetch the string and use it for UI component properties.
Better to show the case in another way. First, please refer to to image for the solution structure:
From the picture, "MobileReplicaBase" is a class library. Please not the two selected file. In "UIresources.resw", I defined a string resource:
And trying to use it in a button control in EdicolaPage:
<Button x:Name="mOpenBtn" Grid.Row="4" x:Uid="OpenBtn" Visibility="{x:Bind Path=type, Converter={StaticResource typeStringToVisibilityConverterForOpenButton}}" Tag="{x:Bind Path=productCode}" Click="mOpenBtn_Click"/>
But this won't work, the Content property for the button is only an empty string. What I can guess is that, the application is trying to load the "OpenBtn" resource from resource map in project "MobileReplica", which is currently the start up project in the solution.
Note: the button may be in a datatemplate in a GridView, so fetch the resource in C# code may not be a good idea.
Problem solved. Use following code to access resource in a class lib:
<Button x:Uid="/{library_name}/{resource_file_name}/{resource_name}"/>
In my case, I should use:
<Button x:Uid="/MobileReplicaBase/UIresources/OpenBtn">
To access to the resource.

Use certain style only when the Fall Creators Update is detected

As an example, I would like to apply the ButtonRevealStyle to my button:
<Button Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will work, but of course only on a device with the Fall Creators Update installed. How do I disable this for all previous versions of W10?
I know I can use .IsApiPresent() in the code-behind when I want to check for a specific Windows Api but in this case this doesn't seem to be the preferred/recommended solution and I'd like to stick to just XAML for this. Doing it in C# requires referencing every single control with that style in code-behind and manually assigning the style if it's present. I'm pretty sure this is not the best solution in this day and age, where you can set up responsive and animated layouts solely in XAML. Besides, if the button was in a ListView.ItemTemplate just accessing each control would require a few solid lines of code. Not to mention the check itself
Is it possible? Am I missing something?
Edit: Turns out it is possible, and I totally was missing something. Conditional XAML can easily be done and isn't that complex all things considered. It's just a matter of setting a custom namespace in the file (pointing to the same resource as the 'root' namespace, just with the `IsApiContractPresent" check at the end. Yes, it is possible to use that in XAML.
After setting the custom namespace you can then specify attributes that will only be aplied when the certain API is present on the End-User's device. Example:
xmlns:fcu="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
...
<Button fcu:Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will result in the button getting Reveal only on PCs with Fall Creators Update and the previous versions won't be throwing an error.
More info: https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/conditional-xaml
You people clearly like your downvote button a bit too much.
Turns out it is possible, and I totally was missing something. Conditional XAML can easily be done and isn't that complex all things considered. It's just a matter of setting a custom namespace in the file (pointing to the same resource as the 'root' namespace, just with the `IsApiContractPresent" check at the end. Yes, it is possible to use that in XAML.
After setting the custom namespace you can then specify attributes that will only be aplied when the certain API is present on the End-User's device. Example:
xmlns:fcu="http://schemas.microsoft.com/winfx/2006/xaml/presentation?IsApiContractPresent(Windows.Foundation.UniversalApiContract,5)"
...
<Button fcu:Style="{StaticResource ButtonRevealStyle}" Grid.Column="1" Width="38" ... />
This will result in the button getting Reveal only on PCs with Fall Creators Update and the previous versions won't be throwing an error.
More info: https://learn.microsoft.com/en-us/windows/uwp/debug-test-perf/conditional-xaml

When to Use Clicked event or Command Binding?

<Button x:Name="ButtonLogin"
StyleId="ButtonLogin"
Grid.Row="5"
BackgroundColor="#F44336"
BorderRadius="0"
TextColor="White"
Text="Login to Meetup"
Command="{Binding LoginCommand}" />
or
<Button x:Name="ButtonLogin"
StyleId="ButtonLogin"
Grid.Row="5"
BackgroundColor="#F44336"
BorderRadius="0"
TextColor="White"
Text="Login to Meetup"
Clicked="LogMeIn" />
Does the use of one or the other matter specifically when designing a Xamarin app?
Which approach should be used?
Regardless of whether it is WPF XAML, Silverlight XAML or Xamarin XAML, the choice to use one or the other does not affect the end performance of the app for at some point it all gets distilled down to codebehind and ultimately into machine code.
With that said if one uses commanding it can be designed to work within the MVVM paradigm and give direct access to functionality which can be either based on the View, ViewModel and even the Model depending on how it is set up.
Since a command is based on ICommand interface, that gives the XAML more flexibility to either allow or disallow operations due to the CanExecute functionality which is a big selling point if used.
Both can be used in Xamarin xaml template[?]
The click event is local to the control and cannot be used in a template. The click event can work with MVVM but it should not be called from anywhere outside the View that contains it.
My advice is to use Commanding where re-use particulary amongst Pages/Views is prevalent and also if there exists a need to either directly or indirectly affect styles and visibility; use it. Otherwise if the operation is just local to the page/control there is no reason not to use code-behind.

How to get an icon in stackPanel in a XAML file

I am new to XAML and C#
I have an icon created already in a project and and I have to use this icon whenever I select one of the option from the dropdown menu.
I made a stackpanel in XAML file
<StackPanel Name="stackPanelforIcon">
</StackPanel>
In the code behind file I have different cases for the dropdown menu.
case IconOnSelect:
?????? = IconList.NewIcon;
This NewIcon is the one already created and I am using the source also for this
using IconProject.Iconlists;
On writing IconList.NewIcon I am not getting any error, it is referenced correctly.
What should I write at ?????? to reference it. Is there any other way apart from using stackPanel to include an icon
A StackPanel cannot show an icon on it's own. You need a control for it, for example an Image.
<StackPanel Name="stackPanelforIcon">
<Image x:Name=theImage" />
</StackPanel>
Then you can use your Icon in your code behind like this:
this.theImage.Source = IconList.NewIcon;
You may need to convert your value, you never said what type it actually is.
Please note that using code-behind is not the preferred way with WPF. Using MVVM is way easier and more natural working with WPF, using code-behind you will fight WPF all the way. Using MVVM, this could be:
<StackPanel Name="stackPanelforIcon">
<Image Source="{Binding CurrentImage}" />
</StackPanel>
with your ViewModel having a property called CurrentImage that you would set when you want to change it. Don't forget to implement INotifyPropertyChanged for the changes to take effect though.

Change a section of a window upon click event

I have a treeview at the left side of the screen, and when I click on any of the TreeViewItem, I want the right side of the screen to change accordingly.
For example, clicking on 'Project' would display on the right half of the screen, a label for project name along with the project name in a text box, and a similar label-textbox pair for some other fields. Clicking on a sub-option of 'Project' such as 'Task 1' should change the right half of the screen such that instead of labels and textboxes for project name and details, it should now be for task name/details. Atm, I only care about label-textbox pairs but in the future I'll need some more sophisticated options, maybe buttons and tables.
What I thought of was to have a grid premade for each option, when I clicked on 'Project' there would be a grid which displays all the info for a Project. And when I then clicked on 'Task 1', the Project grid should be hidden and the Task grid should be displayed with the fields filled out.
Is this possible? What should I be using to create templates that I can then choose from?
Firoz already mentioned the important bit. A rough guess is that you're not using MVVM pattern, so to minimize the adaption effort, you could add a Content Control to your window and set the content of this control whenever a selection is made. You can put any User Control in there.
Using MVVM would mean you bind that Content Control to a property on your ViewModel (of type UIElement or UserControl) and set an instance whenever a bound selected values changes. Speaking of selected Value, I think the default TreeView is not really Binding-friendly, so you might end up with behaviours that do the binding for you.
What you are asking to do is quite easy and possible, but I don't think you are thinking quite big enough.
As your project grows and the number of different things that you want to show expands, then you are going to need to show and hide more and more controls. This is quite quickly going to get unmanageable. Instead think about some other controls deal with this, in some ways you are doing something very like a tabbed dialog, just with a hierarchical set of tabs.
A tabbed dialog has a panel and a set of tabs, when you click on each tab, the content of the panel changes. In fact you can create UserControls one for each specialised set of UI that you want to display, e.g. you could have a ProjectControl that displays all of your project textboxes, labels, buttons etc.
In addition WPF has this neat feature called DataTemplates, these define how a type of data should look when it is displayed. So if you where to have a
public class MyProject
{
public string Name {get;set;}
}
Then you could define
<DataTemplate DataType="{x:Type MyProject}>
<TextBox Text="{Binding Name}"/>
</DataTemplate>
And WPF will automatically convert the data into to its visual form if you set it as the content of the tab panel.
However this type of displaying content in a panel is not the only WPF control that does this. There is also something called a NavigationFrame, which also can be used wrapped into a Window as a NavigationWindow. This control provides you ways to navigate to the next Page to display. Pages can be just like the UserControls in a tabbed dialog, but can also be URIs, enabling you to link in content from the web if you wish. In addition you can call NavigateTo from other controls enabling you build much more usable interfaces.
I worked through the process of building a full windows control panel style interface in
http://alski.net/post/2012/01/11/WPF-Wizards.aspx
and http://alski.net/post/2012/01/13/WPF-Wizards-part-2-Glass.aspx
I've added later VS2012 style glows in
http://alski.net/post/2013/09/14/WPF-Re-creating-VS2012Office-2013-window-glow.aspx
And then released the entire source code as open source at
http://winchrome.codeplex.com/
This comes with support for embedding Navigation panels with
<WinChrome:SearchableNavigationWindow
x:Class="WinChrome.Win7Demo.MainWindow"
...
xmlns:WinChrome="clr-namespace:WinChrome;assembly=WinChrome"
Style="{StaticResource Win7NavigationWindow}">
<WinChrome:SearchableNavigationWindow.Navigation>
<view:Navigation x:Name="navigationTree"/>
</WinChrome:SearchableNavigationWindow.Navigation>
(Full source code)
Where the navigation window is embedded as, but can also be a TreeView.
<UserControl x:Class="WinChrome.View.Navigation" ...>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Padding="12,0"
VerticalScrollBarVisibility="Auto" >
<StackPanel>
<Button
Margin="0,12,0,0" Style="{StaticResource LinkNavigatorButtonStyle}"
Content="Home"
Command="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Win7Demo:MainWindow}, AncestorLevel=1},
Path=GoHomeCommand}" />
</StackPanel>
</ScrollViewer>
(Full source code)

Categories