Text in PhoneTextBox disappears - windows-phone-7

What can I do in the following situation?
I have a simple page. In code behind I add PhoneTextBox control for some filtering of a data. But sometimes (frequently) when I try to write something, I see, that text inside is transparent or collapsed or something else, so I don't see it. I don't see it even when I select this text.
// Generating of a PhoneTextBox
SearchBox = new Microsoft.Phone.Controls.PhoneTextBox();
SearchBox.DataContext = searchBoxContext;
SearchBox.Name = string.Format("SearchBox_{0}", Guid.NewGuid());
SearchBox.Visibility = Visibility.Collapsed;
// Adding Phone text box in a Grid on the Page
RowDefinition rd = new RowDefinition();
rd.Height = GridLength.Auto;
PageDynamicGrid.RowDefinitions.Insert(0, rd);
Grid.SetRow(generator.SearchBox, 0);
foreach (FrameworkElement child in PageDynamicGrid.Children)
{
Grid.SetRow(child, Grid.GetRow(child) + 1);
}
SearchBoxContext = (generator.SearchBox.DataContext as SearchButtonModel);
SearchBoxContext.SearchTextChanged += SearchBoxContext_SearchTextChanged;
generator.SearchBox.TextChanged += SearchBox_TextChanged;
generator.SearchBox.LostFocus += SearchBox_LostFocus;
generator.SearchBox.KeyUp += SearchBox_KeyUp;
generator.SearchBox.DataContext = null;
PageDynamicGrid.Children.Add(generator.SearchBox);
PageDynamicGrid.UpdateLayout();
and page.xaml
<Grid x:Name="PageDynamicGrid" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="{Binding Title}"
Style="{StaticResource PhoneTextTitle1Style}" />
</StackPanel>
<ListBox Grid.Row="1" Margin="12,0"
ItemsSource="{Binding PageDynamicContent, Mode=OneWay}"/>
</Grid>
Almost all content of this page (including search box) creates dynamically, but other content is some buttons and links and I need to filter it, if I have search box. Filter works, but users don't like collapsed text in search box. So it looks like that (and there is not a whitespaces in front of the marker)

So, i don't know why, but it seemed that problem is in the order of actions:
First of all create element, change grid column and row definitions
and add element in the grid.
Update layout of the grid.
And only after all this actions we can collapse PhoneTextBox.
it works for me.

Related

Is there a way I can pass a grid name or a parameter into a tapped event?

I have this code and somehow I want to get the text value of the first label to the tapped event in the CS code. As the tapped event is on the grid I had an idea of putting the text value into x:Name.
<ViewCell >
<Grid VerticalOptions="CenterAndExpand" x:Name="{Binding [0].Name}" Tapped="atiSelectValueX" >
<local:StyledLabel Text="{Binding [0].Name}" HorizontalOptions="StartAndExpand" />
<local:StyledLabel IsVisible="{Binding [0].IsSelected}" TextColor="Gray" HorizontalOptions="End" Text="x" />
</Grid>
</ViewCell>
The CS code I have so far:
void atiSelectValueX(object sender, EventArgs e)
{
var cell = sender as Grid;
if (cell == null)
return;
var selected = cell. <<< I want to get the name here
What I would like to do is to get the x:Name value in the CS code. I was hoping to get the sender information but it seems like I cannot enter
cell.Name
Is there another way I can get a parameter like the name (which is the same as the text in the first label always) in the C# code?
The x:Name is metadata used by the XAML tools, not an actual property of the object. You could also bind Name to an unused property, like StyleID, and access that instead
<Grid VerticalOptions="CenterAndExpand" StyleId="{Binding [0].Name}" ...
and then
var selected = cell.StyleId;

Enabling/disabling ads depending on app status

I would like my ads to be shown while my app is trialed and disappear when app is fully licensed.
Kookiz-
Private Sub PhoneApplicationPage_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs)
If App.IsTrial Then
AdControl1.Visibility = Windows.Visibility.Visible
Else
AdControl1.Visibility = Windows.Visibility.Collapsed
End If
End Sub
The problem is that IsEnabled still shows the Control.
What you should do is add an empty container for the ad in your XAML file, like this:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel x:Name="spAd" Grid.Row="0">
<!--Ad will be placed here via the code-->
</StackPanel>
</Grid>
Then in the PhoneApplicationPage_Loaded event handler, if IsTrial equals true, instanciate the AdControl and add it to the View:
AdControl _adControl = new AdControl();
// Use your real Application ID and Ad Unit ID here
_adControl.ApplicationId = "test_client";
_adControl.AdUnitId = "Image480_80";
_adControl.Width = 480;
_adControl.Height = 80;
spAd.Children.Add(_adControl);

WP7 discards MouseLeftButtonUp if didn't receive ButtonDown

I'm trying to get an element to fire the MouseUp event when the user clicks/taps outside of it, drags into it, then lets go. This type of functionality works in Silverlight, but not WP7. I can't figure out how to get it to work in WP7.
I created a simple app that demonstrates this. In a brand new WP7 app I added this to the content panel:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Green" />
<Grid x:Name="g2" Grid.Row="1" MouseLeftButtonUp="Grid_MouseLeftButtonUp" Background="Blue" />
</Grid>
Then the Grid_MouseLeftButtonUp handler in the codebehind:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
System.Diagnostics.Debug.WriteLine("MouseUp in " + (sender as Grid).Name);
(sender as Grid).Background = new SolidColorBrush(Colors.Red);
}
Run this app and notice the MouseUp event fires fine if you release the button in the same cell you pressed down, however it doesn't fire if you drag from one cell to the other. How can I make the MouseUp event fire?
P.S. I also posted this on the app-hub forms, but no response yet: http://forums.create.msdn.com/forums/p/98004/584400.aspx
My solution is a bit like ShawnFeatherly's, but without TouchFrame.
Basically, as he says, if you call MouseCapture from the grid where the MouseDown event occured, the MouseUp will be triggered on the same grid. So we know how to be notified when MouseUp occurs, the only problem left is how to know in which grid the MouseUp actually occured.
For this, we're going to use the VisualTreeHelper.FindElementsInHostCoordinates method, as it returns all the elements at a specified coordinate.
So, first add a MouseLeftButtonDown event handler to each of your grids:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
((Grid)sender).CaptureMouse();
}
Now in the MouseLeftButtonUp event handler of each of your grids, first release the mouse capture, then retrieve the Grid in which the MouseUp occured:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault();
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}
Note that a problem may occurs depending on your visual tree: if you have multiple grids and wants to detect the MouseUp only on some, you need a way to identify them. For this, I suggest to use the Tag property. Tag is an all-purpose field available on each control, that you can use however you need. It's especially useful for identification purposes.
Start by adding it to the grids that interest you:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="g2"
Grid.Row="1"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>
Then use exactly the same logic in code-behind, but this time add a filter when browsing the visual tree:
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var grid = (Grid)sender;
grid.ReleaseMouseCapture();
var mouseUpGrid = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(this), this.ContentPanel)
.OfType<Grid>()
.FirstOrDefault(element => element.Tag is string && (string)element.Tag == "dragdrop");
if (mouseUpGrid != null)
{
Debug.WriteLine("MouseUp in " + mouseUpGrid.Name);
mouseUpGrid.Background = new SolidColorBrush(Colors.Red);
}
}
And you're done! This code should be able to handle complex scenarios like:
<Grid x:Name="ContentPanel"
Grid.Row="1"
Margin="12,0,12,0"
MouseLeftButtonUp="ContentPanel_MouseLeftButtonUp">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="g1"
Background="Green"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
<Grid x:Name="DummyGrid" Grid.Row="1">
<Grid x:Name="g2"
Background="Blue"
MouseLeftButtonDown="Grid_MouseLeftButtonDown"
MouseLeftButtonUp="Grid_MouseLeftButtonUp"
Tag="dragdrop" />
</Grid>
</Grid>
One way to work around this is listening to the TouchFrame for a TouchAction.Up. You'll have to calculate the UIElement the ButtonUp cooresponds to using the TouchPoints' Position property as described here: http://forums.create.msdn.com/forums/p/98004/584465.aspx#584465
Another way is to capture the mouse in the ButtonDown UIElement. This will cause the ButtonUp to correctly fire, however the sender will be the original UIElement that caused the ButtonDown. You can track the elements the mouse moves through using MouseEnter and MouseLeave. The necessity for mouse capture is briefly touched on here: http://forums.create.msdn.com/forums/p/70785/431882.aspx
Last time I checked, my phone didn't have a mouse attached.
Use the Tap event instead of MouseLeftButtonUp. For more complicated gestures, use the Silverlight Toolkit GestureListener class.
Use MouseLeave event
http://vantsuyoshi.wordpress.com/2012/02/01/wp7-mouseleftbuttonup-not-fired-issue/

No DataBinding when rendering a UserControl+ItemsControl in WriteableBitmap?

I want to use a WriteableBitmap to render a programmatically instantiated UserControl to a jpg/png image to use it as a live tile background image in a Windows Phone 7.1 project, but DataBinding is not working as expected when rendering the control.
In general, the UserControl is something like this:
<UserControl>
<Grid x:Name="LayoutRoot" Height="173" Width="173" >
<Grid.Background >
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Grid.Background >
<Grid.RowDefinitions>
<RowDefinition Height="27"/>
<RowDefinition Height="146"/>
</Grid.RowDefinitions >
<ItemsControl Grid.Row="1" Margin="10,0,0,0" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MyBindingProperty, FallbackValue=xxx}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Hello World" FontSize="22" Margin="5,0,0,0"/>
<TextBlock TextWrapping="Wrap" Text="{Binding Count, FallbackValue=-1}" FontSize="18.667" Margin="123,0,0,0"/>
</Grid>
</UserControl>
When I now put this control onto a PhoneApplicationPage and assign a list with items of my data structure to the DataContext property of the UserControl, everything works fine and I see one TextBlock for each list item and the Text property of that TextBlock is correctly displaying the value of the property of my data structure. Also the last TextBlock on the Grid displays correctly the current count of list items.
BUT when I'm now trying to programmatically create that UserControl, assign the same list to the DataContext and then use a WriteableBitmap to render it to an image file, it seems that all DataBindings within the DataTemplate of the ItemsControl aren't working anymore, they're displaying the FallbackValue now. Although the DataBinding of the outer TextBlock in the Grid is still working perfectly and also I got the correct number of TextBlocks in the StackPanel (= items in the bound list).
Here is my code for creating the the WriteableBitmap:
var tile = new MyTileControl { DataContext = this._myList };
tile.Arrange(new Rect(0, 0, 173, 173));
tile.Measure(new Size(173, 173));
var bmp = new WriteableBitmap(173, 173);
bmp.Render(tile, null);
bmp.Invalidate();
What's the problem with the DataBindings in the DataTemplate when rendering through a WriteableBitmap and how can I solve it?
I think, that your control not fully created yet, and you can't grab bitmap just after creation. Try to use Dispatcher.BeginInvoke or something else for delayed grabbing of image.
Also, add this control to your page and look where is a problem - in control creation or in bitmap? This give you more information about a problem.

Is it possible to access an external class' member variable in page.xaml.cs?

I'm developing a Windows Phone 7 app, and I have two xaml pages. From the first one, I embed two app bar links to select an image from gallery or capture an image using the camera. I would like the image chosen on the first page to be displayed on a second page, with the app bar buttons showing a confirm yes or no. As of now, I have an image control on the first page (barcodeImage) that gets updated with the choice.
MainPage.xaml
<controls:PanoramaItem Header="welcome">
<ScrollViewer Name="sv1" VerticalScrollBarVisibility="Auto">
<StackPanel Height="1100">
<TextBlock TextWrapping="Wrap">Random text here.
</TextBlock>
<Grid x:Name="Grid2" Grid.Row="1" Margin="12,0,12,0">
<Image Height="150" Margin="28,30,168,0" Name="barcodeImage" Stretch="Fill" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" />
</Grid>
</StackPanel>
</ScrollViewer>
</controls:PanoramaItem>
MainPage.xaml.cs
void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
barcodeImage.Source = bmp;
}
}
Confirm.xaml
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Margin="64,36,57,100" x:Name="barcodeImageFinal" Stretch="Fill" />
</Grid>
I'd like barcodeImageFinal to display the final bitmap. How can I make this work? Thanks for looking :)
As I understand your question, you want to create a bitmap in a member of MainPage and then access it from Confirm. One approach would be to create a public static property of some class for your bitmap. For example, maybe create public static BitmapImage FinalBitmap in your App. Then you could set the value of the property in your cameraCaptureTask_Completed and then create a Loaded handler in your Confirm class that sets image source to the stored bitmap.
I think the answer to your question title is yes if you make the member static, although the other class isn't really "external". A normal class member won't be accessible because you don't have an instance of that class.

Resources