ChangePropertyAction on Image Control in LongListSelector item template - image

I have a long list selector and i have a datatemplate as item template, containing an image. I want the source to change based on a property from the model. I tried with a converter but i could't get it to work.
Now i'm trying with triggers. I have:
<Image Name="MovieThumbnail">
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding DataContext.IsCategoryCurrent,ElementName=LayoutRoot}" Value="true">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MovieThumbnail}" TargetName="Source" Value="{Binding Path=Image120x170}" PropertyName="Source"/>
</ei:DataTrigger>
<ei:DataTrigger Binding="{Binding DataContext.IsCategoryCurrent,ElementName=LayoutRoot}" Value="false">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MovieThumbnail}" TargetName="Source" Value="{x:Null}" PropertyName="Source"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
</Image>
It work almost how i want it to, except that images repeat themselves. As in a movie has the picture of another movie. I think it's because i bind by element name and the image control has multiple instances (one for each item), but i would think they can't see each other. Any help highly appreciated.
EDIT:
After further investigation, it seems that this happens because of the long list selector.
I first load 40 items, and then load another 40, but the second batch of 40 items get the pictures from the first batch. If i raise a property changed event, then the pictures from the second batch are set on all items repeating themselves. I have no idea why this is happening.
If i load another 40 and raise property changed on IsCategoryCurrent again, the pictures from the 3rd batch get set 3 times.

I managed to fix it:
<Image
Grid.RowSpan="2"
Name="MovieThumbnail"
Stretch="Fill"
Width="130" Height="195"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding DataContext.IsCategoryCurrent,ElementName=LayoutRoot}"
Value="true">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MovieThumbnail}"
TargetName="Source"
PropertyName="Source">
<ei:ChangePropertyAction.Value>
<BitmapImage CreateOptions="BackgroundCreation"
UriSource="{Binding Path=Image120x170}"/>
</ei:ChangePropertyAction.Value>
</ei:ChangePropertyAction>
</ei:DataTrigger>
<ei:DataTrigger Binding="{Binding DataContext.IsCategoryCurrent,ElementName=LayoutRoot}"
Value="false">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MovieThumbnail}"
TargetName="Source"
Value="{x:Null}"
PropertyName="Source"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
</Image>
And i raise a property changed event of IsCategoryCurrent at every change.

Related

How to use same string resource for different item types

I have a String called Products.Label which is use for an AppBarButton. How can I use the same string for a TextBox without the app crashing?
MainPage.xaml
...
<AppBarButton Name="AppBarButtonProducts" x:Uid="Products"/>
...
Settings.xaml
...
<TextBlock x:Uid="Products/Label" Style="{StaticResource HeaderTextBlockStyle}" />
...
How to use same string resource for different item types
You could make x:string resource in the application resource for different control like the following.
<Application.Resources>
<x:String x:Key="Placeholder">Placeholder Content</x:String>
</Application.Resources>
<TextBox
Height="44"
PlaceholderText="dddd"
Text="{StaticResource Placeholder}"
/>

MultiDataTrigger.Conditions Binding to UserControl specified in another xaml file

Is it possible to create TabItem MultiTrigger that will bind to Valiation.HasError property from a control that:
is a part of another UserControl
UserControl is defined in another xaml file
UserControl is a child of TabItem where MultTrigger is defined
Main xaml file:
<telerik:RadTabItem Header="Data">
<telerik:RadTabItem.Style>
<Style TargetType="{x:Type telerik:RadTabItem}" BasedOn="{StaticResource {x:Type telerik:RadTabItem}}">
<Setter Property="HeaderTemplate" Value="{StaticResource TabItemErrorTemplate}"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<!-- does not work -->
<Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:EquipmentDetailsTabBasicData}}, Path=InputName.(Validation.HasError)}" Value="False"/>
<!-- works only if UserControl content is inculded directly in TabItem -->
<Condition Binding="{Binding ElementName=InputPiecesCount}, Path=(Validation.HasError)}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="HeaderTemplate" Value="{StaticResource TabItemTemplate}"/>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</telerik:RadTabItem.Style>
<local:EquipmentDetailsTabBasicData x:Name="TabBasicData"/>
</telerik:RadTabItem>
local:EquipmentDetailsTabBasicData xaml file looks like this:
<UserControl>
<Grid>
<telerik:RadMaskedTextInput
x:Name="InputName"
Value="{Binding Name, ValidatesOnDataErrors=True, NotifyOnValidationError=True}"/>
<telerik:RadMaskedNumericInput
x:Name="InputPiecesCount"
Value="{Binding PiecesCount, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=TwoWay}"
/>
</Grid>
</UserControl>
MultDataTrigger conditions shows my attempts to bind to controls in child UserControl - both do not work.
I can just move UserControl contents to RadTabItem. When I do the second version (binding by ElementName) works OK. I would like to avoid it because it makes my xaml file hard to maintain.
The first version is taken from this answer, but it does not work and I think that because UserControl is not an ancestor of RadTabItem.

How to use checkbox in datagrid in silverlight

i am making an application in silver light.In that application i am using data grid as
<data:DataGrid Grid.Row="1" HorizontalAlignment="Left" IsReadOnly="True" Name="dataGrid1" VerticalAlignment="Top" AutoGenerateColumns="False" DataContext="{Binding}" SelectionMode="Single" LoadingRow="ResultsGrid_LoadingRow">
<data:DataGrid.Columns>
<data:DataGridTextColumn Header=" BedId " Binding="{Binding BedID }" />
<data:DataGridTextColumn Header="PatientName" Binding="{Binding PatientName}" />
<data:DataGridTextColumn Header="AdmitDate" Binding="{Binding AdmitDate}" />
<data:DataGridTextColumn Header="BirthDate" Binding="{Binding BirthDate}" />
<data:DataGridCheckBoxColumn Header="checkbox" Binding="{ Binding }" IsReadOnly="False" />
</data:DataGrid.Columns>
</data:DataGrid>
Whenever in my application i am loading the data grid, it shows the data grid along with respective values.In my application i want to show the check box in front of every column and above code shows the check box in front of every column. but whenever i am clicking on that check box it doesn't shows any check event.i want to select single or multiple check boxes as per condition.But i am not getting how to do it.Please help me.Thanks in advance.
You have a few options.
1. Setup a selection changed event on the datagrid and whenever a row is selected modify the bound checkbox in that aspect.
If you need more control such as an event to fire when the checkbox is selected I would repalce the DataGridColum with an DataTemplate such as:
<DataGridTemplateColumn Header="Checkbox">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Path=someProperty, UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_Click"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Then in your code behind
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
//I realize you don't have message box in silverlight but this demonstrates the firing of the event
MessageBox.Show("click");
}

Apply the sorting of a datagrid to another datagrid

My client has this requirement :
i.e. a grid with collapsible columns. The easiest way I found to do that is to have 3 separate datagrids and 2 buttons, showing or collapsing the grids.
Here is the associated XAML:
<StackPanel Orientation="Horizontal" Grid.Column="2" Grid.Row="0" VerticalAlignment="Stretch">
<toolkit:DataGridDragDropTarget VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch">
<sdk:DataGrid Name="Grid1" SelectionChanged="Grid_SelectionChanged" AutoGenerateColumns="False">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Binding="{Binding somefield}" Header="someheader" />
<sdk:DataGridTextColumn Binding="{Binding somefield}" Header="someheader" />
<sdk:DataGridTextColumn Binding="{Binding somefield}" Header="someheader"/>
<sdk:DataGridTextColumn Binding="{Binding somefield}" Header="someheader" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</toolkit:DataGridDragDropTarget>
<Button Content=">" Click="Button_Click" Name="btn1" />
<sdk:DataGrid Name="Grid2" SelectionChanged="Grid_SelectionChanged" AutoGenerateColumns="False" ItemsSource="{Binding ItemsSource, ElementName=Grid1}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="someheader" Binding="{Binding somefield}" />
<sdk:DataGridCheckBoxColumn Header="someheader" Binding="{Binding somefield}" />
<sdk:DataGridCheckBoxColumn Header="someheader" Binding="{Binding somefield}" />
<sdk:DataGridTextColumn Header="someheader" Binding="{Binding somefield}" />
<sdk:DataGridTextColumn Header="someheader" Binding="{Binding somefield}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
<Button Content=">" Name="btn2" Click="Button_Click"/>
<sdk:DataGrid Name="Grid3" SelectionChanged="Grid_SelectionChanged" AutoGenerateColumns="False" ItemsSource="{Binding ItemsSource, ElementName=Grid1}">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn Header="someheader" Binding="{Binding somefield}" />
</sdk:DataGrid.Columns>
</sdk:DataGrid>
</StackPanel>
This is working correctly. My problem occurs when I want to sort one of the grid. As the sorting is internal to the datagrid, the changes are not propagated to the other (even tough they are bound to the same source !).
Is there a way to "propagate" the sorting to the other grids ? I tried to find a way to intercept a sorting event, but it doesn't seem to exist...
Thanks in advance !
Why use 3 database?
It's better to use just 1 database and a Options page where the person can hide his / her columns.
you can hide to columns by using DataGrid.Columns[0].Visibility = Visibility.Collapsed.
You can do this with a button above the column.. or a checkbox somewhere... or a options page. Lots of oppertunaties. The only downside is that this can't be implemented in MVVM since DataGridColumn dont support Visibility Binding.
As a answer to your question:
Perhaps this information helps you, just apply sorting to both datagrids
private void Sort_DataGrid(object source, System.Web.UI.WebControls.DataGridSortCommandEventArgs e)
{
// Never use Queries like this always use Stored procedures
SqlCommand myCommand = new SqlCommand("SELECT * FROM Categories", myConnection);
myCommand.CommandType = CommandType.Text;
SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand);
DataSet ds = new DataSet();
myAdapter.Fill(ds,"Categories");
DataView dv = new DataView(ds.Tables["Categories"]);
if( (numberDiv%2) == 0 )
dv.Sort = e.SortExpression + " " + "ASC";
else
dv.Sort = e.SortExpression + " " + "DESC";
numberDiv++;
myDataGrid.DataSource = dv;
myDataGrid.DataBind();
}
Source: http://www.codeproject.com/KB/webforms/SortingDataGridColumns.aspx
If you stick to the three DataGrid solution I think you'd better wrap them in a control and add some sort buttons to this control. The buttons should then trigger the sorting of ALL datagrids.
Another way is to use 1 DataGrid and change the visibilty of the column(s) you would want to hide.

Default Validation Template not getting fired in WPF

My code goes as follows :
<TextBox >
<TextBox.Text>
<Binding Path="SaveAsText" ValidatesOnDataErrors="True" ValidatesOnExceptions="True" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<val:SaveTextValidator></val:SaveTextValidator>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={x:Static RelativeSource.Self},
Path=(Validation.Errors), Converter={StaticResource errorConverter}}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Now when a validation error happens, the ToolTip is getting displayed but the default validation template of making a TextBox border red is not firing !!
Where am I going wrong?
You are overwriting the default style of the TextBox (basically saying: do nothing unless I tell you to).
I imagine there is some trigger in the default style that makes the border red. Either implement it your self or base your style on the current default.
<Style BasedOn={x:Type TextBox} ...>

Resources