I am using an ItemsControl in WP application to show a list of objects ( bind an observable collection to this list).
In WPF we can update the UI if any object properties is updated , but when it comes to WP8 , how can i do the same? Below is the syntax used in WPF , but in WP8 it shows Triggers not found
<ItemsControl>
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataTemplate.Triggers>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
how can i update UI in WP8 ? What i am planning to do is based on the property of an Object set the visibility of a button in the Items.
Rather than use a Trigger. How about using a converter (implementing IValueConverter) to set the visibility based on the property. So your xaml would look like:
<button visibility="{binding YourObjectProperty, Converter={staticresource YourVisibilityConvert}} ... />
Then whenever the propertychanged event is fired for the property, the ui will update visibility based on the value returned by the converter.
you could try to set behavior using Expression blend
xmlns:ec="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" x:Class="XXX_XXXX"
<Image Source="/Assets/Images/Tick.png"
Stretch="None"
HorizontalAlignment="Stretch"
VerticalAlignment="Top">
<interactivity:Interaction.Triggers>
<ec:DataTrigger Binding="{Binding Change}" Value="False">
<ec:ChangePropertyAction PropertyName="Source">
<ec:ChangePropertyAction.Value>
<BitmapImage UriSource="/Assets/Images/Close.png"/>
</ec:ChangePropertyAction.Value>
</ec:ChangePropertyAction>
</ec:DataTrigger>
</interactivity:Interaction.Triggers>
</Image>
Msdn
Related
How can i have a loading/progress bar on the page while it is taking time to call a service,also until the call and response is not complete the controls should not be accessible
Try this way, Create a empty grid behind the Progress Bar that cover the whole screen and set its opacity of say 0.5 so that background is paritially visible.
<Grid Grid.Row="0" x:Name="GrdProgressBar" Background="Transparent" >
<Grid Background="White" Opacity="0.5"></Grid>
<StackPanel VerticalAlignment="Center">
<ProgressBar IsIndeterminate="True" Foreground="Green" Margin="0,5,0,0" ></ProgressBar>
<TextBlock Text="loading.." FontSize="20" FontStyle="Italic" Foreground="Black" HorizontalAlignment="Center" ></TextBlock>
</StackPanel>
</Grid>
What you have to done set the visibility of `GrdProgressBara as you do with ProgessBar.
Hope it help you :)
Another way is to use a property IsLoading that is true while the service call is in progress and false after the call finished. Then you can use a converter and bind your IsEnabled property of your controls to the inverse IsLoading value. So while your service call is running, all controls are disabled and when the call finishes, the control will be reenabled. You just need to set the IsLoading property and bind within XAML. No additional code needed.
I have a longlistselector for which I have a data template that defines the type of items to be added to the list. The data template has an Image control whose source is binded with path dynamically, thus each item in list has an associated Image Control. The problem I face is that these Image control never free the memory they occcupy resulting in out of memory exception. On normal scenario I set bitmapImage.UriSource=null to deallocate the memory associated with the bitmap But can't find a way to do so in this scenario. Here is the xaml code for the longlistselector and the data template associated with it..
Data Template
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="MediaItemTemplate">
<Canvas VerticalAlignment="Top">
<Border BorderBrush="#FF4791CA" BorderThickness="3">
<Image Height="100" Width="100" VerticalAlignment="Top" Grid.RowSpan="2" Stretch="UniformToFill">
<Image.Source>
<BitmapImage UriSource="{Binding path}" CreateOptions="BackgroundCreation" DecodePixelHeight="50" DecodePixelWidth="50"/>
</Image.Source>
</Image>
</Border>
<Image Source="/Icons/check.png" Height="16" Width="16" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="80,7,7,0" Canvas.ZIndex="100" OpacityMask="Black" Visibility="{Binding visibility}" Name="checkImage" >
</Image>
</Canvas>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
LonglistSelector
<phone:LongListSelector
Tap="ListMedia_Tap"
x:Name="ListMedia"
HorizontalAlignment="Left"
Height="624"
VerticalAlignment="Top"
Width="436"
Background="Transparent"
ItemTemplate="{StaticResource MediaItemTemplate}"
LayoutMode="Grid" GridCellSize="120,120"/>
I am very new to windows phone programming, What basically I want to do is to develop kind of image browser experience. Please Help me out with ways to deallocate the memory. In case I am doing it completely wrong please correct me or suggest better ways to achieve the same functionality. Thanx in advance...
A solution I've found to handle this case is making a custom control to automatically set the urisource to null:
public class SafePicture : System.Windows.Controls.ContentControl
{
public SafePicture()
{
this.Unloaded += this.SafePictureUnloaded;
}
private void SafePictureUnloaded(object sender, System.Windows.RoutedEventArgs e)
{
var image = this.Content as System.Windows.Controls.Image;
if (image != null)
{
image.Source = null;
}
}
}
Then, just wrap all your pictures in that control:
<my:SafePicture>
<Image Source="{Binding Path=path}" />
</my:SafePicture>
By default Windows Phone stores messages downloaded from a Uri in memory to save having to load them again. (It's a crude form of caching.)
To free the memory used by these images you needed to explicitly free all references to them. See MSDN: Image Tips for Windows Phone 7 for more details
When scrolling with your code (without using Loaded), then images are lost after scrolling down and returning to the top of the list (speed no matter). While using Loaded, scrolling wokrs okay: it is possible to scroll down and return to the top, (debugger shows that Unloaded and Loaded are called), and images are there. However, when moving to another page (i have master-detail pages), they are mixed up.
I am developing app in WIndows phone 8 and using LLS with this data template..
<phone:LongListSelector Name="longlist">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding property1, Mode=TwoWay}" Content="Hii" Checked="CheckBox_Checked_1" Unchecked="CheckBox_Unchecked_1"/>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
While I checked one and scroll list the checkbox selection is changed suppose I select first it shows up me 2 is selected or no-one is selected means behave differently..I am using code in .CS in this link...
http://pastie.org/7938678
please suggest me how can I get rid off this problem..
That is by design. You just tapped a check box inside a list item, thereby selecting it.
I suggest you don't rely on list selection position changed, use another event like Tap instead in your DataTemplate to drive any actions you have based on a list item.
If you want only 1 Item selected at a time use a RadioButton instead of a CheckBox. After this you need to define the GroupName Property.
See the code of my answer below:
How to highlight a selected item in the LongListSelector on WP8?
I have a GridView in a windows store app that has an ItemContainerStyleSelector. Within the style is an Image control that has a custom dependency property to set the source (This is so I can get a handle on the Image and hook up to the unloaded event).
My issue is the Image is never unloaded and seems to be reused. This means that when I set the source, the image is set on other items in the GridView as well (For Example I have an object which has no image but after scrolling away and then back again it has an image from another object).
I've tried to set virtualization mode to standard where I can but it doesn't help. Any ideas would be greatly appreciated.
Here is the Image that is contained in the style. This is passed to a method "OnRemoteURISourceChanged" when set. I'd expect a different image control whenever the method is called but this is not the case.
<Image x:Name="BackgroundImage" DataContext="{Binding CurrentBackdrop}" helpers:ImageExtensions.RemoteURISource="{Binding Uri}" Stretch="UniformToFill"/>
And here is my GridView
<GridView x:Name="ItemsGrid" Grid.Row="1" ItemsSource="{Binding BrowseResults}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" Margin="20,0,20,0"
IsItemClickEnabled="True" ItemClick="ItemsGrid_ItemClick" VirtualizingStackPanel.VirtualizationMode="Standard">
<GridView.ItemContainerStyleSelector>
<controls:UPnPCDStyleSelector CDObject="{StaticResource somestyle1}" Container="{StaticResource somestyle2}" Item="{StaticResource somestyle3}"/>
</GridView.ItemContainerStyleSelector>
<GridView.ItemsPanel>
<ItemsPanelTemplate VirtualizingStackPanel.VirtualizationMode="Standard">
<WrapGrid Orientation="Vertical" VirtualizingStackPanel.VirtualizationMode="Standard"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
UPDATE: The issue appears to be the WrapGrid. If I change this to a VirtualizingStack Panel and set the VirtualizationMode to Standard then everything works as expected but obviously my items then only appear on one line and not multiple lines as I wish.
How do I set the virtualization mode of a WrapGrid?
Is there a chance your helpers:ImageExtensions.RemoteURISource doesn't clear the Image.Source when either your CurrentBackdrop property or its Uri property value is null?
Are you sure the task which is loading the img source returns to default ui context when awaiting? I don't think it is a good idea to set Image.Source property form code. The better solution would be to create a custom observable task class and bind im source to it's result. In the background you can call the task. Do you need the control to be Image? Because if it would be a control with template, it would be easier for you to do that. I can send you the class which does that if you want to.
I needed to access to the ActualWidth of a Border that didn't have a specified Width. I have been told that I can't do that on WinRT so I used a proxy from Florian-Gl (from here).
The thing is that I need to create that proxy on the page's resource like this:
<Page.Resources>
<utils:ActualSizePropertyProxy Element="{Binding ElementName=noteBorder}" x:Name="proxy" />
</Page.Resources>
The problem is that I don't have access to that noteBorder element from the resources, but I have access to pageRoot that is the Page itself.
I guess that I can play with ElementName / Path to get access to noteBorder.
But there is some curious stuff:
The structure is something like:
Page (pageRoot) > Grid > ListView > ListView.ItemTemplate > Grid > Border (noteBorder)
So, If I create the proxy at the same level of the border, It won't run but If I change the ListView to a ItemsControl, it will run and works as expected.
If having it at the same level of the border I change the ElementName to pageRoot it will run at least.
So, It won't run if I put noteBorder (even when I have access to it) if I'm using a ListView, but will work on a ItemsControl, On the other hand, If I have pageRoot it works all ways.
So the question is: Is there a way to access noteBorder from resources? Or maybe a way to access it from another place but working :P
You should be using an Item Template --
By the time you get to
pageRoot) > Grid > ListView or Items Control
At this point in the structure, you're at the element you really want to get at, which is the container of the items that will need the border you are trying to access.
You should define an Item Template and assign the ListView's (or ItemsControl's) ItemTemplate property via binding.
<ListView x:Name="myListView" DataContext="{Binding ToElementIfNotInheritedFromParent}" ItemsSource="{Binding ViewModelListBeingBoundTo}" ItemTemplate="{Binding Source={Static Resource MyCustomItemTemplate}}" />
Where MyCustomItemTemplate is something like
<DataTemplate x:Name="MyCustomItemTemplate">
<Border x:Name="myBorder" >
<StackPanel>
<TextBlock Text="{Binding Path=Title}" />
<TextBlock Text="{Binding Path=FirstProperty}"/>
<TextBlock Text="{Binding Path=SecondProperty}"/>
</StackPanel>
</Border>
</DataTemplate>
Then In your Codebehind (or if ViewModel use the code behind to pass the ListView object to the ViewModel)
DataTemplate dt = this.myListView.Items[indexOfChoice].ItemTemplate as DataTemplate;
Border b = dt.LoadContent() as Border;
int actualWidth = b.AcutalWidth
OR
You can create a FindControl() method that runs recursively to extract the actual control within the border, for instance if you wanted to access one of the Textboxes.
The code for that is here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a612f5a6-e05e-4b68-a813-893eeda159cc