WP7 Binding in App.xaml Application.Resources - windows-phone-7

In App.xaml <Application.Resources>
I have:
<Color x:Key="ColorMain">#FF1F879C</Color>
<SolidColorBrush x:Key="ColorBrushMain" Color="{StaticResource ColorMain}"/>
then I have many templates which are using this brush and color. These templates are used all over the application.
I need to have an ability to change the color to change the skin of whole application.
I need something like:
<SolidColorBrush x:Key="ColorBrushMain" Color="{Binding ColorMain}"/>
and in code something like:
public string ColorMain {
get {
return ..... ; // "#FF803200";
}
}
But it doesn't work. Please help.
UPD: abhinav is right it must be a color
public Color ColorMain {
get {
return ..... ; // return Color.FromArgb(0xFF, 0x80, 0x32, 0x00);
}
}
but this is not enough, it's not binding. I assume that it must be something as on normal page with DataContext to ViewModel, but what?

If you're binding to a property that stores the Color and you're going to change at runtime and expect it to update, don't you need to be implementing INotifyPropertyChanged as well? For example:
public class MyViewModel: INotifyPropertyChanged
private Color _mainColor
public Color MainColor
{
get { return _mainColor; }
set
{
if (value != _mainColor)
{
_mainColor= value;
NotifyPropertyChanged("MainColor");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
So: if you're expecting to change the color at runtime, use binding and implement INotifyPropertyChanged - if the colour isn't going to change at runtime, what you've already got should be fine.

You're binding a color property to a string object.
Although I've never tried it, I'm quite sure that it will not work.
Maybe the documentation of the class will help. See this link.
Did you try using the color class instead?
public Color ColorMain {
get {
return ..... ; // "#FF803200";
}
}

Related

Is there a way to update bounded data when I swipe back [PopAsync() ]

To provide some context, I'm writing a Xamarin.Forms application and utilizing data binding with INotifyPropertyChanged. Currently I have an inventory counter displayed on a button. The text on this button displays the bounded "Count" variable (e.g Current Inventory: 35). When I press the button, I push a screen onto the navigation stack which allows me to edit this "Count" variable. I use the class implementation like this
public class UserInventory : INotifyPropertyChanged
{
private int count = 0;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;
public int Count
{
get => Preferences.Get(nameof(Count),0);
set
{
if (count == value || value <1)
return;
Preferences.Set(nameof(Count), value);
//count = value;
//Application.Current.Properties["Count"] = count;
OnPropertyChanged(nameof(Count));
//OnPropertyChanged(nameof(displayName));
}
}
public UserInventory()
{
}
void OnPropertyChanged(string count)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(count));
}
}
I add this class in Xaml according to the tutorial on the Xamarin <ContentPage.BindingContext>
<local:UserInventory />
</ContentPage.BindingContext>
So the variables are bounded correctly and I have no issues seeing updates on the current page or when I push new pages. The issue is when I swipe back on iOS the previous screen with the button "Current Inventory: 35" does not update to reflect the new changes. If I push that screen the changes are reflected.
Is there anyway to ensure the bounded data is updated when you go back (PopAsync()) ?
Try overriding page's OnAppearing() method and call OnPropertyChanged from there.
Assuming 'UserInventory' the binded VM.....
public partial class Page1:ContentPage
{
public Page1()
{
InitializeComponent();
VM = (UserInventory)BindingContext;
}
public UserInventory VM { get; }
protected override void OnAppearing()
{
VM.Notify();
base.OnAppearing();
}
}
.
public class UserInventory: INotifyPropertyChanged
{
........
public void Notify()
{
OnPropertyChanged(nameof(Count));
}
}

xamarin picker SelectedItem returning null on observable collection

in my xamarin project, picker binding, the SelectedItem is not working. When I have the ItemSource set to a List, the SelectedItem works, but when I change the ItemSource to an ObservableCollection, the SelectedItem always returns null. Can someone see what I am doing wrong?
on loading the view, the pickers are populated through databinding. then on a button event I try and grab the SelectedItem.... which is when it is coming back as null.
xaml
<Picker x:Name="PickerMarket2" Title="Market2" ClassId="PickerMarket2"
ItemsSource="{Binding TestList2}"
ItemDisplayBinding="{Binding ShortDesc}"
SelectedItem="{Binding SelectedMarket}"
Grid.Row="0" Grid.Column="1" >
</Picker>
view model
class VamiMarketViewModel: INotifyPropertyChanged
{
private List<string> _testList;
public List<string> TestList
{
get { return _testList; }
set
{
{
_testList = value;
NotifyPropertyChanged();
}
}
}
private ObservableCollection<Performance> _testList2;
public ObservableCollection<Performance> TestList2
{
get { return _testList2; }
set
{
{
_testList2 = value;
NotifyPropertyChanged();
}
}
}
private string _selectedMarket;
public string SelectedMarket
{
get { return _selectedMarket; }
set
{
{
_selectedMarket = value;
NotifyPropertyChanged();
}
}
}
I just explained the same in your other question here.
To what I see from your code, the SelectedItem seems to be the problem.
Since your Picker's ItemsSource(TestList property) is of type List<Performance>, the SelectedItem property bound to the Picker must be of type Performance. But, in your case, you have kept it as string instead of Performance.
The ItemDisplayBinding must be the name of any property inside your Performance object which in your case is fine since you have a string property called ShortDesc inside your Performance class.
That's the problem I see in your code. Change the type of the property ShortDesc like below and assign any one of the items in your collection TestList to it. Your code will start working fine.
private Performance _shortDesc;
public Performance ShortDesc
{
get { return _shortDesc; }
set
{
{
_shortDesc = value;
NotifyPropertyChanged();
}
}
}
Refer to the documentation here which explains a clear example for Binding objects to Picker.
I hope that helps.

How to stop a Xamarin Forms behavior used to asynchronously translate an image?

In a Xamarin.Forms project, I'm trying to repeatedly translate an image from a position A(x,y) to a position B(x,y) and back, from B to A. To achieve this, I read that is possible to customize behaviors.
I extend Behavior class, overriding OnAttachedTo and OnDetachingFrom. And in the OnAttachedTo method I start a Task which repeatedly does the two translations.
This is my Behavior class:
public class MoveImageBehavior : Behavior<Image>
{
private Image _Image = null;
public static readonly BindableProperty AnimatedProperty = BindableProperty.Create("Animated", typeof(bool), typeof(ImageAnimatedBehavior), defaultValue: false);
public bool Animated
{
get { return (bool)GetValue(AnimatedProperty); }
set { SetValue(AnimatedProperty, value); }
}
protected override void OnAttachedTo(Image image)
{
base.OnAttachedTo(image);
_Image = image;
Animated = true;
Task.Run(AnimateImage);
}
protected override void OnDetachingFrom(Image image)
{
base.OnDetachingFrom(image);
_Image = null;
}
private async void AnimateImage()
{
while (_Image != null && Animated)
{
await _Image.TranslateTo(100, 100, 1000);
await _Image.TranslateTo(0, 0, 1000);
}
}
}
The image in the xaml file:
<ContentView>
<Grid>
<Image x:Name="image_translating" Source="my_icon" Aspect="AspectFit">
<Image.Behaviors>
<behaviors:MoveImageBehavior Animated="{Binding ImageTranslating}" BindingContext="{Binding BindingContext, Source={x:Reference image_translating}}"/>
</Image.Behaviors>
</Image>
</Grid>
</ContentView>
The Image repeatedly translates correctly as I want, but I'm not able to stop the while routine. The property binding doesn't work when Animated is set to false in the ViewModel and OnDetachingFrom is never called.
What am I doing wrong? Any suggestions?
Through the document, we can see that:
The OnDetachingFrom method is fired when the behavior is removed from
the control. This method receives a reference to the control to which
it is attached, and is used to perform any required cleanup. For
example, you could unsubscribe from an event on a control to prevent
memory leaks.
It will only fired when you remove the behavior from the image. I would give you an example about how to stop the animation:
I defined an bool property in the code behind to control stop or not stop:
public bool showA = true;
And I add a button as an example to stop the animation:
private void Button_Clicked(object sender, EventArgs e)
{
showA = !showA;
if (showA)
{
image_translating.Behaviors.Add(new MoveImageBehavior());
}
else
{
var toRemove = image_translating.Behaviors.FirstOrDefault(b => b is MoveImageBehavior);
if (toRemove != null)
{
image_translating.Behaviors.Remove(toRemove);
}
}
}
Also in your OnDetachingFrom method, do not set the image to null, it will cause a null expection, just set the Animated to false :
protected override void OnDetachingFrom(Image image)
{
base.OnDetachingFrom(image);
Animated = false;
}
You can convert my click event to some binding in your project and make it work.
Refer: creating-a-xamarinforms-behaviorer

CustomRenderer to dynamically change border color

I have an Entry, which I want to add a red border around when a button is pressed if the entry is empty. Therefore I need to be able to change the color dynamically. (standard validator)
xaml:
<local:BorderChange Placeholder="Example Entry" BorderColor="#ff4444"></local:BorderChange>
PCL Control:
namespace Project
{
public class BorderChange : Entry
{
public string BorderColor
{
get;
set;
}
}
}
iOS Customrenderer:
[assembly: ExportRenderer(typeof(BorderChange), typeof(BorderColorChange))]
namespace Project.iOS
{
public class BorderColorChange : EntryRenderer
{
//init color
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if(Control != null)
{
Control.Layer.BorderColor = UIColor.Blue; //This is where i want to add my color
}
}
}
}
How do I pass my property to the CustomRenderer, so that I can change the BorderColor parameter dynamically?
A better approach for such needs is to use Effects.
Here is a well-described example of how to create an effect with parameters as attached properties. You'll be able to bind a property from your view model (Let's say IsValid directly to the attached property of the effect).

Xamarin Switchcell binding IsEnabledPropery not working?

I'm just creating a simple example where I want to enable/disable a Switchcell (named switch2) by turning on/off another switchcell (named switch1).
I'm using the binding method. I've tried this code with an "Entry" element (trying to disable it) and it works perfectly, but with the property "IsEnabledProperty" of "switchcell" it seems not working. (I'm not using Xaml, i'm using PCL).
Xamarin Forms updated to the latest version (2.3.0.49).
Is this a Xamarin issue?
Here's the code:
BindingContext = new DetailsViewModel();
SwitchCell switch1 = new SwitchCell()
{
Text = "Switch",
};
switch1.SetBinding(SwitchCell.OnProperty, new Binding("Test", BindingMode.TwoWay));
SwitchCell switch2 = new SwitchCell()
{
Text = "Visibilita",
};
switch2.SetBinding(SwitchCell.IsEnabledProperty, "Test");
and here is the DetailsViewModel.cs:
public class DetailsViewModel : INotifyPropertyChanged
{
bool test;
public bool Test
{
get { return test; }
set
{
if (test != value)
{
test = value;
OnPropertyChanged("Test");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var changed = PropertyChanged;
if (changed != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Actually this is bug from Xamarin, I think is not yet fixed first check without binding whether is working or not

Resources