Button Styling in XAML - windows-phone-7

I have customized the button in this way:
<Button BorderBrush="Transparent" Name="DialButton" Click="DialButton_Click" >
<StackPanel Orientation="Horizontal">
<TextBlock FontSize="43" Name="lblNumber" Margin="0,-5,0,0" />
<TextBlock FontSize="12" Margin="5,20,0,0" Name="lblCharacter" />
</StackPanel>
</Button>
Now, when a user presses the button I want the OnPress state to change the color of the labels. I can do this if it's a simple button by changing the Pressed state. But my label is placed inside a stack panel. How can I change the color in this case? Or in which event can I change the colors of the labels from C#.

You can use the PropertyChangeAction in cases like this. You can find this in the behaviors category on the Assets tab in Expression Blend.
Apply this action on the labels. Change the trigger property to the DataTrigger instead of the default EventTrigger. Bind the trigger to the IsPressed property of the DialButton. Add two PropertyChangeActions per TextBlock and set the Value for one of the to true and the other one to false.
Here's an example for one of them. The other is exactly the same.
<TextBlock FontSize="43" x:Name="lblNumber" Margin="0,-5,0,0" Text="25">
<i:Interaction.Triggers>
<ec:DataTrigger Binding="{Binding IsPressed, ElementName=DialButton}" Value="true">
<ec:ChangePropertyAction PropertyName="Foreground">
<ec:ChangePropertyAction.Value>
<SolidColorBrush Color="Red"/>
</ec:ChangePropertyAction.Value>
</ec:ChangePropertyAction>
</ec:DataTrigger>
<ec:DataTrigger Binding="{Binding IsPressed, ElementName=DialButton}" Value="false">
<ec:ChangePropertyAction PropertyName="Foreground">
<ec:ChangePropertyAction.Value>
<SolidColorBrush Color="{StaticResource PhoneForegroundColor}"/>
</ec:ChangePropertyAction.Value>
</ec:ChangePropertyAction>
</ec:DataTrigger>
</i:Interaction.Triggers>
</TextBlock>
If the i: or ec: isn't working, make sure you've got these lines at the top of your xaml file.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ec="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

You'll need to turn this into a custom control and then you can manage the styling of each component based on the state.

Try this in the click event of button
Button butClicked = (Button)sender;
StackPanel panel1 = (StackPanel)butClicked.Content;
var child1Panel1 = panel1.Children[0] as TextBlock;
child1Panel1.Foreground = new SolidColorBrush(Color.FromArgb(255, 18, 18, 18));

If you're only going to use this button once, probably the easiest way would be to open the .xaml file in Expression Blend, and use Blend to customize the button as you wish, including the state change. If you're using the button in more than one place, do as Matt suggested and make it a custom control (which you can also use Blend to design) that you can reuse.

Related

How can I keep a Xamarin label on screen with data bound to a Carosell Item

I have a
<CarouselView ItemsSource="{x:Static vm:MainPageViewModel.MyItems}">
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Label Text="{Binding ID}"/>
<Label Text="{Binding Progress}"/>
...
I would like the <Label Text="{Binding Progress}"/> not to scroll off screen, but to stay fixed (at the top) and update as the user swipes through the CarouselView items. If I move the label outside of the CarouselView, it won't be data bound.
How can I keep the label fixed onscreen, but bound to the curren CarouselView item? (Do I need to do this via code behind?)
You can achieve this easily by binding the text property of the Label to the property in your ViewModel which will also do binding to the CurrentItem property of CarouselView.
Can you try something like this:
<Label Text="{x:Static vm:MainPageViewModel.MyCurrentItem.Progress}"/>
<CarouselView CurrentItem="{x:Static vm:MainPageViewModel.MyCurrentItem}"
ItemsSource="{x:Static vm:MainPageViewModel.MyItems}"
... other code
>
... other code
</CarouselView>
and in your ViewModel create a new bindable property of the same type as your MyItems list items are.
I have updated my GitHub repo with the example of this kind of behaviour:
You can find GitHub repo here.
and particular view here.
And here is a GIF of a running demo:
Label is above the CarouselView, and when you swipe and change the selected item, the value of label is changing according to the change of CarouselView.
Hope this was helpful for you, wishing you lots of luck with coding!

Xamarin Picker add TagGesture

I'd like to add a tap gesture to the Picker - so when a value is selected (double tapped) I can call a method. I have tried the following. But it never fires! Any ideas?
<Picker Grid.Row="5" Margin="0,0,100,0" Title=" -Select State" SelectedIndex="{Binding StatesSelectedIndex, Mode=TwoWay}" ItemsSource="{Binding PPStates}" ItemDisplayBinding="{Binding Path=[display_name]}">
<Picker.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding OnTapPicker}"
NumberOfTapsRequired="1" />
</Picker.GestureRecognizers>
</Picker>
I have tired the sample code in
https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/gestures/tap/
By adding this Tapped="OnTapGestureRecognizerTapped"
I don't know how you could do that in the way you desire, but you could fire the selectedindexchanged. If I'm right this should fire when the user selected one of the 50 states. Here you have some documentation about the picker.
https://developer.xamarin.com/api/type/Xamarin.Forms.Picker
If you want to use a picker that is bindable you should use this:
https://forums.xamarin.com/discussion/30801/xamarin-forms-bindable-picker
let me know if this helped you.
Edit:
Pickers are bindable by default nowadays

How to add a button to first item in ListView

Greeting,
I'm developing an apps for Windows Phone 8.1 and face some problem with ListView.
I wanted to place a button for the FIRST item in ListView, but it seem like I can't align center the button.
Below is the code I use currently:
<ListView>
<Button Content="Jio!" Height="6" Width="362"/>
<ListViewItem Content="ListViewItem"/>
</ListView>
Adding horizontalalignment='center' just wont work for the button.
The reason I want to do this is because I wanted the button to scroll together with the list, hence I'm placing it inside the ListView.
Please advice what can I do to achieve my purpose, thanks!
I recommend using the ListView.Header content to place such a button instead of adding it as a child directly.
<ListView>
<ListView.Header>
<Button ... HorizontalAlignment="Center" />
</ListView.Header>
</ListView>
By default, the ListViewItems are left-aligned. You will eventually have to replace their Template in order to center-align it (HeaderTemplate Property).

How to make repeating textblocks in Windows Phone 7?

Databinding still confues me and I am not sure how to essential make these controls repeat for each bound piece of data I have.
<Grid>
<TextBlock FontSize="25" Text="this is a header"></TextBlock>
<TextBlock Height="30" HorizontalAlignment="Left" Margin="19,36,0,0" Name="txt" Text="line under the header" VerticalAlignment="Top" />
<TextBlock Height="30" FontSize="25" HorizontalAlignment="Left" Margin="306,9,0,0" Name="textBlock2" Text="530" VerticalAlignment="Top" Width="91" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="305,42,0,0" Name="textBlock3" Text="30" VerticalAlignment="Top" Width="91" />
</Grid>
If my data source would have a count of 50. I would expect to see 50 of these groupings(I probably need to get a scroll bar though).
Not sure how to do this though. I need some sort of datatemplate I guess? Also "line under the header" should be clickable and highlight.
I think you need to use the control named "ItemsControl". Not a derived class, not a ListBox, just plain simple ItemsControl.
Either in code or in XAML, you set the ItemsControl's ItemsSource property to any collection containing your items.
In XAML (either in VS or Blend, to do it WYSIWYG in Blend you must somehow provide design data) you set the ItemsControl's ItemTemplate to a DataTemplate that contains the XAML subtree you want to repeat for every item in your collection.
Inside the DataTemplate, replace "line under the header" with the Button control, with Content="line under the header", and style it however you want. Then, add CallMethodAction to your button. It only takes 2 clicks in Blend, the first one is on "Assets" window. Specify TargetObject="{Binding}" MethodName="actSubtitleClicked". This way, the framework will call the void actSubtitleClicked() method of the item where user clicked the "line under the header".
For best performance, you should also modify the ItemsControl's ItemsPanel template, replacing StackPanel with VirtualizingStackPanel (again, a few clicks in Blend, the first one is the right click, then "Edit additional templates / ItemsPanel / Edit a copy")

Extremely confused about ContentPresenter

FYI I'm pretty new to Silverlight.
Okay, so I want to build a simple user control that contains a button plus some additional XAML as specified by the client of the control.
I got searching on Google and found at least 30 different articles that were all very confusing; especially because they talk about styling animation, customizing other controls that you don't own, and other crap I'm not ready for yet.
This is what I did.
In VS 2010, I right clicked and added a new UserControl called MyControl
To the MyControl.xaml I changed the LayoutRoot to a StackPanel and added a Button inside it
In my MainPage.xaml I added an instance of MyControl
I added a TextBox as a child element of this instance
I tried to build and got an error that MyControl didn't support Direct Content
Googled some more..
I changed MyControl to inherit from ContentControl and updated the xaml
I added a ContentPresenter in the xaml to represent the client "custom content"
Okay, it builds and the TextBox shows up, but the Button is missing.
Here's the relevant section from MainPage.xaml
<my:MyControl HorizontalAlignment="Left" Margin="49,26,0,0" x:Name="myContentControl1" VerticalAlignment="Top" Height="550" Width="389">
<TextBox Height="72" HorizontalAlignment="Left" Margin="166,339,0,0" Name="textBox1" Text="TextBox" VerticalAlignment="Top" Width="460" />
</my:MyControl>
Here's the MyControl.xaml
<ContentControl x:Class="ContentControlTest.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="480" d:DesignWidth="480">
<StackPanel x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Orientation="Vertical">
<ContentPresenter/>
<Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="78,254,0,0" Name="FooFoo" VerticalAlignment="Bottom" Width="160" />
</StackPanel>
</ContentControl>
And here is the MyControl.cs
using System.Windows.Controls;
namespace ContentControlTest
{
public partial class MyControl : ContentControl
{
public MyControl()
{
InitializeComponent();
}
}
}
The way I thought it worked was that the child elements of the control instance are set as the Content property on the ContentControl base class of MyControl. Then, ContentPresenter "pastes" that content into the MyControl.xaml wherever appears.
Although that does seem to be how it works, in the process it is "eating" the Button that I have defined in the MyControl.xaml.
I'm trying not to get into ControlTemplate etc that at this point unless it is absolutely necessary.
Can someone with a clue please tell me what I am doing wrong.
thanks!
That's because the Content of the control is the entire StackPanel you've written by hand; when you set a new Content, the StackPanel is replaced.
A ControlTemplate is necessary for this scenario, I think; it would be a very simple one after all. The starting point can be the default style of the content control; put the style inside a ResourceDictionary (for instance, in the <ContentControl.Resources> section of your user control), and you're ready to go; all you need to do is add a grid and button inside that template.
Note that the style I linked to sets itself as the default for any reachable ContentControl; to make it only apply to your control and not to any children that may appear inside it, add x:Key="someKey" to the Style and set the ContentControl's Style property explicitly to Style={StaticResource someKey}.
Let me know if you need additional information; also, I might be wrong and there may be an easier way, but I doubt it; the Content property is meant to behave exactly like what you described.

Resources