How to access to Base DataContext property in C# code behind? - c#

I have got a class that gaves me a list of images with two URL addresses as property, one for thumbnail and second for full image. In XAML code of different class I successfully bound to those thumbnail data and showed thumbnails of images. Although now I wanna work with second property in C# code after click on thumbnail and I don't know how to access to DataContext. Thank you for a help.
http://s30.postimg.org/ecx7qepnl/prb2.png

As you can see in debugger DataContext is set to instance of MyPlaces.FlickrImage so all you need to do is get the value of img.DataContext and cast it to your type:
var flickrImage = img.DataContext as MyPlaces.FlickrImage;
if (flickrImage != null)
{
// do something with flickrImage.Image1024
}

Related

Find original SOURCE attribute value

I have an application where I'm taking a XAML template from a database record, plugging in new text strings and image references, and showing it in a window.
I take the XAML text and create a DependencyObject using this property:
public DependencyObject ParsedXamlTree
{
get
{
String xaml;
DependencyObject theDependencyObj;
xaml = ProcessedXaml;
byte[] xamlData = Encoding.Unicode.GetBytes(xaml);
using (MemoryStream ms = new MemoryStream(xamlData))
{
theDependencyObj = (DependencyObject)XamlReader.Load(ms);
}
return theDependencyObj;
}
}
Within the XAML will be an Image tag. For example:
<Image x:Name="categoryImage"
HorizontalAlignment="Center"
Height="240"
Margin="72,42,408,318"
VerticalAlignment="Center"
Width="320"
Source="SampleAssets\pacman-151558_640.png"/>
The problem I'm having is that when I parse the DependencyObject tree and get to the corresponding Image object, the string "SampleAssets\pacman-151558_640.png" from the Source attribute seems to be missing.
I notice that when it reads and parses the XAML, there is an IO exception being thrown within WPF itself. That's the line where XamlReader.Load is called. This exception is caught within the library so I'm only seeing evidence of it in the debug trace window.
I'm guessing that it's trying to find "SampleAssets\pacman-151558_640.png" for the Image tag and failing. That's fine in itself, as I always figured the image sources would have to be patched up at runtime.
The question is, how do I retrieve the "SampleAssets\pacman-151558_640.png" string that was in the original XAML? Is there somewhere in the Image object I can get this?
Worst case scenario would be parsing the XAML myself to find the tag and extracting the attribute string from it, but I'm hoping that's not necessary.
WPF has a built-in type converter (ImageSourceConverter) that converts URI strings to ImageSource objects (the type of the Image.Source property). If an image could not be loaded from an URI string, the converter returns null, so the Source property of your Image control will also be null.
There is nothing in the object tree that will keep the URI of a non-available image. You will have to parse the XAML Template before loading and replace invalid image URIs by valid ones.

How does FindViewById() work?

I'm new in mobile app development. I'm using Xamarin to develop Android applications. In the hello world app in the OnCreate method I see the following code:
Button button = FindViewById<Button>(Resource.Id.MyButton);
So I'm trying to create my own button the same way. I create the button in the designer and inside OnCreate method put the line:
Button myOwnBtn = FindViewById<Button>(Resource.Id.MyOwnBtn);
That gives me an error that there is no MyOwnBtn. Then I'm looking the code of Id class and see there a line like:
public const int MyButton=2123344112;
If I put there the line:
public const int MyOwnBtn=2123344113;
Everything works fine. But as I understand it should be generated automatically or it will be a little bit difficult to put there a unique number for each control.
Can anybody tell me what I am doing wrong? And how does FindViewById() work?
You have to give the id MyOwnBtn to the Button that you created in the designer.
findViewById is a method of the View class and it looks for a child view having the id that you provided in the argument.
From official documentation:
Look for a child view with the given id. If this view has the given id, return this view.
MyButton id is not a const value, It will change every launch.
The Activity or ViewGroup's findViewById() method returns a view that already has an id. The findViewById() method should be used in conjunction with XML layouts to provide a reference to the View that was defined in the XML file.
Edit: Not entirely sure if my answer is relevant to Xamarin. I apologize if I have mislead people, I am referring to Java Android application development.
When you declare a button in your .xml file, you should set an id for it (Usually it is done using string.xml file). After that, R.java will be updated automatically and set a number to your declared id and you can access your button by that id like what you have done.
It will try to find it from the XML file that you inflate. So make sure you inflate the correct xml file. This code inflates the xml:
SetContentView (Resource.Layout.MainLayout);
Even if you got the correct id created in a xml file, if you don't inflate it first, the system won't be able to find that view since it is not inflated.

WinRT Application

I am busy developing a WinRT Application.
I want to access the value of RichEditBox defined in page BasicPage1.xaml into the code behind the page BasicPage2.xaml i.e in BasicPage2.xaml.cs?
Is there anyway to get the value of the RichEditBox(defined in BasicPage1.xaml) in BasicPage2.xaml.cs ?
Thanks in anticipation.
Are you familiar with MVVM? Basically the idea is to not rely to much on the control layer for business data, instead share these information on another layer, in this case the model or view model.
So lets say you want to want to load a project and have a dialog with a textbox containing the path to a project, which the user can modify. So you would store the path in a model called ProjectInformation, this object you can now pass to other views (to be more precise, view models and then views) and use the data there. The important part here is lifetime, your model propably lives much longer than your view, so the data is stored and reused in the places where its necessary.
A simple way to do this is to give your textbox a name in the XAML and then access that textbox via the name in the code behind.
<TextBox Name="myTextBox"/>
then in the code behind you can do this
myTextBox.Text = "blah";
A better way is to use binding so that updating the textbox automatically updates the property you are bound to. Have a look at this post textbox binding example
For a rich edit textbox you should be able to do this:
set
myTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, "Here is text");
get
string value = string.Empty;
myTextBox.Document.GetText(Windows.UI.Text.TextGetOptions.AdjustCrlf, out value);
See this post for more information
Do you need to send it through when navigating to the other page? Then you can do it like this:
this.Frame.Navigate(typeof(BasicPage2),textbox.Text);
and at the BasicPage2.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var textbox= e.Parameter;
...
}
But i also highly recommend using MVVM in your application. With MVVMLight you can implement this quite easy and quick.

Windows 8 questions (Why App.Current.Resources? Why Use GridView Items?)

I have 2 questions regarding a tutorial that I am going through.
Q1.
Through the tutorial they use a datasource
Using the data in the app
To use the data in the app, you create an instance of the data source
as a resource in App.xaml. You name the instance feedDataSource.
BR211380.wedge(en-us,WIN.10).gifTo add a resource to an app
Double-click App.xaml in Solution Explorer. The file opens in the XAML editor.
Add the resource declaration, <local:FeedDataSource x:Key="feedDataSource"/>, to the root ResourceDictionary, after the
MergedDictionaries collection.
and then they use it in the OnLaunch method.
var connectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
if (connectionProfile != null)
{
FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"];
if (feedDataSource != null)
{
if (feedDataSource.Feeds.Count == 0)
{
await feedDataSource.GetFeedsAsync();
}
}
}
I am wondering why do they store it in resource? Wy not just create an instance of the class and get the results from it?
Q2.
Later down the article they use this datasource items with "grid view items". I seen this done in their other template projects. I am wondering is there the standard way of making your interface?
At first I thought maybe just drop some image buttons on the screen and hook up their click events but now I am not sure.
The XAML Resource essentially does create an instance for you and makes it available in the Resources collection, so you could instantiate the class yourself. Having it as a resource keeps this object around and makes it accessible across the various pages in your application. You could certainly create the class explicitly, and if you enforce the singleton pattern on it, it would be semantically equivalent.
I'm not sure I see the context of your second question in the tutorial, but in general the pattern you are seeing is Model-View-ViewModel (MVVM), which is the de facto standard pattern for Windows Store apps. feedDataSource is providing the model and portions of that are assigned to DefaultViewModel, which is the DataContext for all of the binding markup in the XAML pages, which are the views. The idea behind this to separate your data from your model, so that when you do things like load a new data feed, etc., all you need to do is change the data source, and all of the data binding markup will automatically reflect the new data in your user interface.
If you find yourself writing code that looks like TextBox.Text = "My text", then you're deviating from the pattern.

MvxHttpImageView binding not updated

I have the following code
<Mvx.MvxHttpImageView xmlns:local="http://schemas.android.com/apk/res/TestServices.Droid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
local:MvxBind="{'ImageUrl':{'Path':'ThumbNail'}}"
Where I am passing an image url to the ThumbNail property. The above code is part of an ItemTemplate which is being passed an ObservableCollection of TestModel objects as below.
public class TestModel
{
public string ThumbNail
{
get;
set;
}
public string Name
{
get;
set;
}
....
}
The Name property is also bound in the above Template to a TextView and it shows up properly as do other string values. The only issue is that the Image does not show up.
I have tried setting the Image Url upfront in the constructor of the ViewModel and it works then. But when I add fetched values to the collection in the Completed event of my web service thats when the Image is not displayed. I have verified the path to the image url in the completed event and it is right. What could be going wrong here. Many thanks
I'm not sure what's going wrong....
But some things to consider experimenting with are:
setting the MvxBindingTrace level to Diagnostic - does the output panel tell you anything interesting?
if you are updating the url dynamically then do you need to fire the property changed event
if you add a textview with its Text bound to the image url, then does this update correctly?
does using wrap_content for both height and width really make sense here? What happens if you fix height and width to 100dp instead?
does the app work if you use known good image URL - eg a URL from http://placekitten.com?
does the app work if you set a default image to a local file (eg a resource or asset) which is shown while the http image is loading?
do the sample apps work for you - eg the bestsellers or twitter samples? If so, then can you see what they do differently?
can you step into the mvx http image source - are the properties and methods being called at all? If they are, then do they look like they are being called correctly or oddly in any way?
Try those suggestions and I suspect you will find a way forwards. Good luck with the debugging.
if these suggestions don't help, please try adding more info, including info on which version of mvvmcross you are using, which version of Android, which phone or emulator, etc.
Got it, I was using backslashes for creating the url by concatenating strings, changing them to forward slashes turned it into a proper link and its working fine now. Thanks a lot for the help Stuart

Categories