LockablePivot throws InvalidCastException - c#

I am trying to implement the lockablePivot control found in the Windows Phone Toolkit - August 2011 (7.1 SDK) release.
When I add an itemtemplate to the control every time i change the isLocked property during runtime it throws a InvalidCastException. Are there any workarounds to this?
Need help. Thanks
<Grid x:Name="LayoutRoot" Background="Transparent">
<toolkit:LockablePivot Name="Pages" SelectionChanged="Pivot_Changed" ItemsSource="{Binding}">
<toolkit:LockablePivot.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Stretch">
<Button Content="Lock" Click="Button_Click"/>
<Image Stretch="Uniform" local:WP7ImageZoomer.IsZoomingEnabled="True" ManipulationStarted="Image_ManipulationStarted" ManipulationCompleted="Image_ManipulationCompleted" ManipulationDelta="Image_ManipulationDelta" CacheMode="BitmapCache">
<Image.Source>
<BitmapImage x:Name="Bit" UriSource="{Binding Img}" DownloadProgress="BitmapImage_DownloadProgress" CreateOptions="BackgroundCreation"/>
</Image.Source>
</Image>
</Grid>
</DataTemplate>
</toolkit:LockablePivot.ItemTemplate>
</toolkit:LockablePivot>
</Grid>
C#:
private void Image_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
this.Pages.IsLocked = true;// Throws InvalidCastException here
}
private void Image_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
{
this.Pages.IsLocked = false;
}
private void Image_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
{
//this.Pages.IsLocked = true;
}

There is an open ticket for that bug. See http://silverlight.codeplex.com/workitem/10793. Please don't forget to vote.

Related

Set Button Image in ControlTemplate

I have this Image Button in my WPF Application:
<Button Grid.Column="2" Content="Play" Focusable="False" Width="100" Height="60" HorizontalAlignment="Left" VerticalAlignment="Center" Name="PlayPauseButton" Click="PlayPauseButton_Click">
<Button.Template>
<ControlTemplate>
<Image x:Name="PlayPauseImage" Visibility="Visible" Stretch="Uniform" Source="/PlayTube;component/images/PlayerApplication/PlayButton.png" />
</ControlTemplate>
</Button.Template>
</Button>
And I want to have the ability to set the Image programmatically, but I can't access PlayPauseImage.
Any idea why it happen?
You can use FrameworkTemplate.FindName to locate control inside your ControlTemplate
var img = PlayPauseButton.Template.FindName("PlayPauseImage", PlayPauseButton) as Image;
Try using FindName:
private void PlayPauseButton_Click(object sender, RoutedEventArgs e)
{
Image image = (Image)PlayPauseButton.Template.FindName("PlayPauseImage", PlayPauseButton);
}
Note: Always use FindName only when the control will be fully loaded, otherwise it will not find it and give null.
Also for this event has:
ContentRendered for Window
Loaded
Make sure the Button is Loaded.. so its better to use the Loaded event to get this...
private void ButtonBase_Loaded(object sender, EventArgs e)
{
var image = PlayPauseButton.Template.FindName("PlayPauseImage", PlayPauseButton) as Image;
}

What event fires when user lifts finger from ScrollViewer on touch capable screens

I'm finding that when I tap the ScrollViewer, the PointerPressed and PointerExited events fires as expected. But, if I scroll in any direction after touching the screen and lift my finger, no event fires except for PointerCaptureLost which prematurely fires as soon as I scroll.
When I capture the pointer ID and poll the status of the PointerPoint with a timer, the IsInContact flag remains true, even after I lift my finger after scrolling. It works as expected when I simply tap the screen.
ManipulationCompleted has the same effect as above, and I cannot use the ViewChanged event since this fires before I lift my finger.
Is this a bug or am I missing something here? Is there another way I can detect when a user has lifted their finger off the screen? This is driving me bananas.
Sample code below. You'll need to use the simulator in touch-mode or have a touch capable screen to test:
Code:
using System;
using Windows.UI.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
namespace App1
{
public sealed partial class MainPage : Page
{
private readonly DispatcherTimer pointerTimer = new DispatcherTimer();
private uint? CurrentPointerID; //container for the current pointer id when user makes contact with the screeen
public MainPage()
{
this.InitializeComponent();
scrollviewer.PointerPressed += scrollviewer_PointerPressed;
scrollviewer.PointerMoved += scrollviewer_PointerMoved;
scrollviewer.PointerExited += scrollviewer_PointerExited;
scrollviewer.PointerReleased += scrollviewer_PointerReleased;
scrollviewer.PointerCaptureLost += scrollviewer_PointerCaptureLost;
scrollviewer.PointerCanceled += scrollviewer_PointerCanceled;
pointerTimer.Tick += pointerTimer_Tick;
pointerTimer.Interval = TimeSpan.FromMilliseconds(300);
pointerTimer.Start();
}
#region ScrollViewer Events
void scrollviewer_PointerMoved(object sender, PointerRoutedEventArgs e)
{
EventCalledTextBlock.Text = "Pointer Moved";
}
void scrollviewer_PointerExited(object sender, PointerRoutedEventArgs e)
{
EventCalledTextBlock.Text = "Pointer Exited";
}
void scrollviewer_PointerPressed(object sender, PointerRoutedEventArgs e)
{
CurrentPointerID = e.Pointer.PointerId;
EventCalledTextBlock.Text = "Pointer Pressed";
}
void scrollviewer_PointerCanceled(object sender, PointerRoutedEventArgs e)
{
EventCalledTextBlock.Text = "Pointer Canceled";
}
void scrollviewer_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
{
EventCalledTextBlock.Text = "Capture Lost";
}
void scrollviewer_PointerReleased(object sender, PointerRoutedEventArgs e)
{
EventCalledTextBlock.Text = "Pointer Released";
}
#endregion
void pointerTimer_Tick(object sender, object e)
{
if (!CurrentPointerID.HasValue)
{
PollingTextBlock.Text = string.Empty;
return;
}
try
{
var pointerPoint = PointerPoint.GetCurrentPoint(CurrentPointerID.Value);
PollingTextBlock.Text = pointerPoint.IsInContact ? "Is In Contact" : "Not in Contact";
}
catch (Exception ex)
{
//This exception is raised when the user lifts finger without dragging.
//assume finger is not in contact with screen
PollingTextBlock.Text = "Not in Contact";
}
}
}
}
XAML:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Name="grid">
<Grid.RowDefinitions>
<RowDefinition Height="113*"/>
<RowDefinition Height="655*"/>
</Grid.RowDefinitions>
<ScrollViewer x:Name="scrollviewer" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible" Grid.Row="1" >
<Rectangle Fill="#FF3783CF" Height="100" Stroke="#FF33D851" Width="{Binding ElementName=grid, Path=ActualWidth}" Margin="100" StrokeThickness="4" />
</ScrollViewer>
<StackPanel Orientation="Vertical" Margin="45,25,0,0">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Event Called:" VerticalAlignment="Top" FontSize="24" Margin="0,0,20,0"/>
<TextBlock x:Name="EventCalledTextBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="Polling Value:" VerticalAlignment="Top" FontSize="24" Margin="0,0,20,0"/>
<TextBlock x:Name="PollingTextBlock" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="24"/>
</StackPanel>
</StackPanel>
</Grid>
</Page>
I stumbled upon this question since I was struggling with a similar problem. I have a ScrollViewer which has several images in it and I wanted to know what images are shown at the moment the ScrollViewer stops moving...
In the end I did used the ScrollViewer.ViewChanged event. This event keeps triggering untill it has finished with scrolling.
I actually am only interested in the last of these events, but since there is no event that triggers only on that particular moment I need to respond to this one and check for myself if this is the appropriate moment to take actions.
I hope this helps.
ScrollViewer.ViewChanged event: https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.scrollviewer.viewchanged?f=255&MSPPError=-2147217396
I think you need to use the PointerReleased event.
Refer to the following link: https://msdn.microsoft.com/library/windows/apps/br208279

Saving user color settings of a clicked Button in WPF

I have a little problem with saving some properties of my Buttons. The Buttons are small and with a variety of colors. When i press one button, some specified colors are changing... and i want to save them for the next start up. The textbox values i can save them but this ...i can't.
Code:
public MainWindow()
{
InitializeComponent();
//blueColor.RaiseEvent(new RoutedEventArgs(Button.ClickEvent));
//this.Property = Properties.Settings.Default.userColor;
}
private void blueColor_Click(object sender, RoutedEventArgs e)
{
var bc = new BrushConverter();
Main.Background = (Brush)bc.ConvertFrom("#FF007CE4");
startButton.Foreground = (Brush)bc.ConvertFrom("#FF007CE4");
closeButton.Foreground = (Brush)bc.ConvertFrom("#FF007CE4");
Properties.Settings.Default.userColor = true;
Properties.Settings.Default.Save();
}
private void purpleColor_Click(object sender, RoutedEventArgs e)
{
var bc = new BrushConverter();
Main.Background = (Brush)bc.ConvertFrom("#FF8701B9");
startButton.Foreground = (Brush)bc.ConvertFrom("#FF8701B9");
closeButton.Foreground = (Brush)bc.ConvertFrom("#FF8701B9");
}
I think I need the last clicked Button to be saved because I have allot of colors and maybe the .RaiseEvent can help here.
This is how it looks like:
Those 3 little buttons:
white
blue
red
are for changing the look of the program. At every start, the default is back.
You can store the color as a simple string and TypeConverter automatically converts it to type Brush. Below is an example.
Binding default value from XAML:
xmlns:properties="clr-namespace:WorkWithSettings.Properties"
<Button Width="100" Height="30"
Background="{Binding Source={x:Static properties:Settings.Default}, Path=Setting, Mode=TwoWay}" />
Set value from code:
private void Button_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.Setting = "#FF007CE4";
}
Note: Setting - this is just the type of String.
More information you can see here:
TypeConverters and XAML
Edit:
Below I'll show you an example, that I hope will help you.
So, go into the settings of the project: Project -> Properties -> Parameters. This opens a window of approximately:
Here we have a property ButtonColor, defined in the settings. For example, I took the Button, which changes the background, depending on the color of the pressed button.
In order to property Background the synchronize with settings to do, so:
<Button Width="100" Height="30"
Content="TestButton"
Background="{Binding Source={x:Static properties:Settings.Default}, Path=ButtonColor, Mode=TwoWay}" />
The default background color of white. Now, to set the background color at the button, we change the parameter settings, like this:
private void Blue_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.ButtonColor = "Blue";
}
To save changes to the settings, you need to call a method Save():
private void Save_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.Save();
}
Now, the next time you start the program, the color will be the one that was set last.
Full example
XAML
<Window x:Class="WorkWithSettings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:WorkWithSettings.Properties"
WindowStartupLocation="CenterScreen"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Width="100" Height="30" Text="{Binding Source={x:Static properties:Settings.Default}, Path=ButtonColor, Mode=TwoWay}" Margin="0,60,0,0" />
<Button Width="100" Height="30" Content="TestButton" Background="{Binding Source={x:Static properties:Settings.Default}, Path=ButtonColor, Mode=TwoWay}" />
<WrapPanel>
<Button Name="Blue" Width="100" Height="30" Content="BlueColor" VerticalAlignment="Top" Click="Blue_Click" />
<Button Name="Red" Width="100" Height="30" Content="RedColor" VerticalAlignment="Top" Click="Red_Click" />
<Button Name="White" Width="100" Height="30" Content="WhiteColor" VerticalAlignment="Top" Click="White_Click" />
</WrapPanel>
<Button Name="Save" Width="60" Height="30" Content="Save" VerticalAlignment="Top" HorizontalAlignment="Right" Click="Save_Click" />
</Grid>
</Window>
Code behind
namespace WorkWithSettings
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void White_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.ButtonColor = "White";
}
private void Blue_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.ButtonColor = "Blue";
}
private void Red_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.ButtonColor = "Red";
}
private void Save_Click(object sender, RoutedEventArgs e)
{
WorkWithSettings.Properties.Settings.Default.Save();
}
}
}
Output
You probably need to create items in the Settings tab of your project that store the information about the color. I would recommend storing the hex strings. Then, on MainForm_Load retrieve those values.
Make sure to also put the settings in the User scope, or else they will reset each time they close the application.

Calling a base-class method from Silverlight XAML

As part of learning Silverlight, I'm trying to create a base UserControl to use as the starting point for my inherited controls.
It's very simple, it merely defines some callback methods:
public class ClickableUserControl : UserControl
{
private Control _superParent;
public ClickableUserControl()
{
}
public ClickableUserControl(Control superParent)
{
_superParent = superParent;
this.MouseEnter += new MouseEventHandler(PostfixedLayoutItem_MouseEnter);
this.MouseLeave += new MouseEventHandler(PostfixedLayoutItem_MouseLeave);
this.MouseLeftButtonDown += new MouseButtonEventHandler(PostfixedLayoutItem_MouseLeftButtonDown);
}
public virtual void PostfixedLayoutItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var elements = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(null), this);
if (elements.Any(elm => elm is ClickToEditTextBox))
{
e.Handled = false;
}
}
public void PostfixedLayoutItem_MouseLeave(object sender, MouseEventArgs e)
{
this.Cursor = Cursors.Arrow;
}
public void PostfixedLayoutItem_MouseEnter(object sender, MouseEventArgs e)
{
this.Cursor = Cursors.Hand;
}
public void ClickToEditTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter || e.Key == Key.Escape)
{
VisualStateManager.GoToState((Control)sender, "NotEdit", false);
_superParent.Focus();
}
}
}
Please note the ClickToEditTextBox_KeyDown() method which is the problem!
Now, I have an inherited control that looks as follows (CheckboxLayoutItem.xaml):
<local:ClickableUserControl x:Class="OpusFormBuilder.LayoutItems.CheckboxLayoutItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:OpusFormBuilder.LayoutItems"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400" x:Name="LayoutItem">
<StackPanel Name="stackPanel1" Orientation="Horizontal">
<lc:LayoutItem Label="layoutItem" Name="layoutItem">
<lc:LayoutItem.LabelTemplate>
<DataTemplate>
<Self:ClickToEditTextBox KeyDown="ClickToEditTextBox_KeyDown" Text="{Binding Label, Mode=TwoWay, ElementName=layoutItem}" MaxWidth="150" MinWidth="150" TextWrapping="Wrap" MaxHeight="200" VerticalAlignment="Top" />
</DataTemplate>
</lc:LayoutItem.LabelTemplate>
<dxe:CheckEdit Name="InnerCheckbox" Grid.ColumnSpan="2" Grid.Column="0" Grid.Row="0" VerticalAlignment="Top" HorizontalAlignment="Stretch" IsEnabled="False" />
</lc:LayoutItem>
<Self:ClickToEditTextBox KeyDown="ClickToEditTextBox_KeyDown" x:Name="Description" MaxWidth="150" MaxHeight="200" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Right" />
</StackPanel>
(Note - I have removed some namespace declarations for easier reading)
Note the following line:
<Self:ClickToEditTextBox KeyDown="ClickToEditTextBox_KeyDown" Text="{Binding Label, Mode=TwoWay, ElementName=layoutItem}" MaxWidth="150" MinWidth="150" TextWrapping="Wrap" MaxHeight="200" VerticalAlignment="Top" />
in which I set the KeyDown-event on a ClickToEditTextBox (the self namespace is defined, and correctly so).
Now, in the code behind (CheckboxLayoutItem.xaml.cs) in the constructor the call to InitializeComponent() fails with the error: Failed to assign to property 'System.Windows.UIElement.KeyDown'. [Line: 17 Position: 42]
I can't debug into InitializeComponent, however, but I can't see what could possibly be the issue from this error, other than the KeyDown events in the XAML.
Now, here is my question - how come I (seemingly) cannot reference a method defined in my base-class!? Previously I had the method in the CheckboxLayoutItem.xaml.cs method itself, but as some other controls needed some of the same functionality, it seemd a better option to put it in a base class.
Cheers!
I know this doesn't really answer your question, but you might want to look at Template (Custom Controls) controls. UserControl really isn't the best solution for what you're trying to do here.
UserControls are best for situations where you're building a one-off control that you don't intend in inheriting from.

does silverlight support streaming through mms?

I am using Windows Server 2008 R2 with Windows Media Service. At the client side, I want to use Silverlight to play the media file. I am using VSTS 2008 + Silverlight 3 + ASP.Net + .Net 3.5. I want to know whether Silverlight supports play mms streaming file from Windows Media Service? If yes, any code samples that I can make a quick test?
The MediaElement in Silverlight supports streaming via mms. You should have a look at the MSDN audio and video overview for Silverlight.
Here is a very basic Silverlight app which can control a MediaElement and shows the media state / buffering status:
XAML
<UserControl x:Class="StreamingTest.MainPage"
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" d:DesignWidth="640" d:DesignHeight="480">
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Vertical">
<MediaElement x:Name="MediaElement" Width="640" Height="480" Source="mms://danarec:8080"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock x:Name="Status" Margin="0,5"/>
<TextBlock x:Name="Buffer" Margin="10,5"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="Play" Content="Play" Click="Play_Click"/>
<Button x:Name="Pause" Content="Pause" Click="Pause_Click"/>
<Button x:Name="Stop" Content="Stop" Click="Stop_Click"/>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
C#
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
this.MediaElement.CurrentStateChanged += (sender, e) =>
{
this.Status.Text = this.MediaElement.CurrentState.ToString();
this.Buffer.Visibility = this.MediaElement.CurrentState == MediaElementState.Buffering ? Visibility.Visible : Visibility.Collapsed;
};
this.MediaElement.BufferingProgressChanged += (sender, e) =>
{
this.Buffer.Text = string.Format("{0:0.0} %", this.MediaElement.BufferingProgress * 100);
};
}
private void Play_Click(object sender, RoutedEventArgs e)
{
this.MediaElement.Play();
}
private void Pause_Click(object sender, RoutedEventArgs e)
{
this.MediaElement.Pause();
}
private void Stop_Click(object sender, RoutedEventArgs e)
{
this.MediaElement.Stop();
}
}

Categories