A good example on how to use UpdateSourceTrigger=Explicit with MVVM - c#

I'm trying to figure out how to use UpdateSourceTrigger=Explicit.
I've got following form:
<StackPanel x:Name="LayoutRoot" Margin="10" DataContext="{Binding ElementName=Window, Mode=OneWay}">
<DockPanel>
<TextBlock Text="Proxy address:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.PageAddress, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="28,0,0,0"/>
</DockPanel>
<DockPanel Margin="0,5,0,0">
<TextBlock Text="User name:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.UserName, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="46,0,0,0"/>
</DockPanel>
<DockPanel Margin="0,5,0,0">
<TextBlock Text="User password:" VerticalAlignment="Center"/>
<TextBox Text="{Binding User.Password, Mode=TwoWay, UpdateSourceTrigger=Explicit}" Margin="26,0,0,0"/>
</DockPanel>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,5,0,0">
<Button Content="Ok" IsDefault="True" Width="70" Margin="0,0,15,0" Click="Ok_Click"/>
<Button Content="Cancel" IsCancel="True" Width="70"/>
</StackPanel>
</StackPanel>
what method should I call to update User property?
I don't want to address the elements by x:Name to invoke the binding. If I have to address the elements by x:Name, I as well can go without binding altogether, as far as I'm concerned.

You need to call BindingExpression.UpdateSource in the code behind to manually update the binding. Explicit binding isn't really compatible with MVVM since you need to directly reference the view objects to perform the manually update.
// itemNameTextBox is an instance of a TextBox
BindingExpression be = itemNameTextBox.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();

Related

How to get Text in GridView when selected?

I'm working on a project in which I'm setting content using JSON Binding in Grid view but now I want to get Text of item when it is selected. XAML CODE:
<GridView ItemsSource="{Binding}" HorizontalAlignment="Center" Margin="0,10,0,0" x:Name="dataList" VerticalAlignment="Center" SelectionMode="None" SelectionChanged="dataList_Selection">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Width="450" Height="300">
<Image Source="{Binding Top}" Margin="0,0,0,0" Stretch="None" />
<TextBlock x:Name="title" Text="{Binding Title}" Foreground="Black" HorizontalAlignment="Center" FontFamily="Assets/Font/MixBrush.ttf#MixBrush" FontWeight="Bold" FontSize="50" Margin="0,10,0,0" />
<Image Source="{Binding Bottom}" Margin="0,0,0,0" Stretch="None" />
<TextBlock Text="{Binding first}" Foreground="Black" HorizontalAlignment="Center" FontFamily="Assets/Font/Comfortaa_Regular.ttf#Comfortaa" FontSize="20" Margin="0,50,0,0" />
<TextBlock Text="{Binding second}" Foreground="Black" HorizontalAlignment="Center" FontFamily="Assets/Font/Comfortaa_Regular.ttf#Comfortaa" FontSize="20" Margin="0,0,0,0" />
<TextBlock Text="{Binding third}" Foreground="Black" HorizontalAlignment="Center" FontFamily="Assets/Font/Comfortaa_Regular.ttf#Comfortaa" FontSize="20" Margin="0,0,0,0" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Here I want to get Text of "title" programmatically. Please share your knowledge with me. :-)
********************** Thank You ************************
On your back code use:
title.Text;
After long hard struggle I found my answer.
var selection = (myClass) dataList.SelectedItem;
await new MessageDialog(selection.Title).ShowAsync();
And I got perfect result.
Thank You.

How to change the ImageSource value of the ImageBrush in the DataTemplate

Am requesting for help on how i can dynamically change the value of the ImageSource for the ImageBrush contained in the DataTemplate.
Below is my XAML Code :
<StackPanel Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal">
<TextBlock Text="{x:Bind first_name}"
Name="TxtFirstName"
Margin="10,0,0,0"
FontSize="18" FontWeight="Bold" FontStyle="Italic"/>
<TextBlock Text="{x:Bind last_name}"
Name="TxtLastName"
Margin="10,0,0,0"
FontSize="18" FontWeight="Bold" FontStyle="Italic"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,40,0,0" HorizontalAlignment="Left" >
<Ellipse Width="200" Height="200" Name="ProfilePicEllipse">
<Ellipse.Fill>
<ImageBrush x:Name="ProfilePic"
ImageSource="{x:Bind image_url}" />
</Ellipse.Fill>
</Ellipse>
<Image x:Name="ResultImage" Stretch="UniformToFill"/>
</StackPanel>
<StackPanel Grid.Row="1" Grid.Column="1" Margin="0,40,0,0">
<TextBlock Text= "{x:Bind profile}"
VerticalAlignment="Center"
Margin="10,0,0,0"
FontSize="18" />
</StackPanel>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Not sure what the actual problem is.
But seeing you are already binding the source to a property, you can always change the value of that in your code.
Do note that nothing will change on screen if you don't put Mode=OneWay to it. Because x:Bind default setting is Mode:OneTime
So instead of ImageSource="{x:Bind image_url}" put ImageSource="{x:Bind image_url, Mode=OneWay}"

On few laptops, WPF Data Grid button does not trigger corresponding bound command function in ModelView

This is my view code sample,
<DataGrid Margin="0,0,0,0" Name="gdProcessDetails" ItemsSource="{Binding AttachmentList}" >
<DataGrid.Columns>
<DataGridTemplateColumn Width="670" IsReadOnly="True" x:Name="btnMemeberDelete" MaxWidth="670" Selector.IsSelected="True">
<DataGridTemplateColumn.HeaderTemplate>
<DataTemplate>
<TextBlock Text="Attach File" Width="650" TextWrapping="Wrap" FontFamily="Arial Unicode MS" FontSize="16" TextAlignment="Center" FontWeight="Bold" />
</DataTemplate>
</DataGridTemplateColumn.HeaderTemplate>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,2" Width="670" Height="40">
<Border BorderBrush="#FF8D7C7C" BorderThickness="1">
<TextBlock Name="txtFilePath" Text="{Binding UploadedFileName, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" Height="32" FontSize="16" FontFamily="Arial Unicode MS" Margin="10,0,5,0" MinWidth="500" MaxWidth="500" />
</Border>
<Button Height="32" HorizontalAlignment="Center" Margin="5,5,0,0" Name="btnUploadDoc" VerticalAlignment="Top" Command="{Binding ElementName=CertificateControl, Path= DataContext.UploadDocCommand}" CommandParameter ="{Binding ElementName=btnUploadDoc}" MinWidth="80">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Browse" FontSize="16" FontFamily="Arial Unicode MS" Margin="0,0,5,0" MaxWidth="100" TextWrapping="Wrap" />
</StackPanel>
</Button>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Data context of this View has 'UploadDocCommand' Icommand property. This is working fine on most of the machine. But on few laptops, clicking on this button does nothing. Any help would be much appreciated. Same result on all over the application wherever Buttons are used inside DataGrid/toolkit:DataGrid. Thanks in advance.
UPDATE : Happens only on 4.0 framework machine
This issue was happening only with Framework 4.0. I have fixed this using RelativeSource instead of ElementName. Changed the button Command property as below and worked. Thanks for all your help.
<Button Height="32" HorizontalAlignment="Center" Margin="5,5,0,0" Name="btnUploadDoc" VerticalAlignment="Top" Command="{Binding DataContext.UploadDocCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}" CommandParameter ="{Binding ElementName=btnUploadDoc}" MinWidth="80">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Browse" FontSize="16" FontFamily="Arial Unicode MS" Margin="0,0,5,0" MaxWidth="100" TextWrapping="Wrap" />
</StackPanel>
</Button>

Modify last (or individual) item inside GridView

I have a GridView which is populated (through binding) by an ObservableCollection. How do I set it up so that every time a new item is added to the ObservableCollection, the last item in the GridView always has a button on top of it ?
This is the XAML of the GridView's ItemTemplate
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="White">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding DateMade}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
My problem lies in this template being applied for all items in the GridView. I want it so that if it's the last item (and the last item would keep changing every time a new item is added), the above StackPanel should be replaced by another control (say, a button). How would I go about doing this ?
I would extend the template of all elements but hide the additional element and only show it if it's the latest element (specified by some bool property that is set to true on the last element). Something like this.
<GridView.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Left" Width="250" Height="250">
<Border Background="White">
<Image Source="{Binding ImagePath}" Stretch="UniformToFill" AutomationProperties.Name="{Binding Title}"/>
</Border>
<Button Visibility="{Binding IsLastElement, Converter={StaticResource BoolToVisibilityConverter}}"/>
<StackPanel VerticalAlignment="Bottom" Background="{ThemeResource ListViewItemOverlayBackgroundThemeBrush}">
<TextBlock Text="{Binding Title}" Foreground="{ThemeResource ListViewItemOverlayForegroundThemeBrush}" Style="{StaticResource TitleTextBlockStyle}" Height="60" Margin="15,0,15,0"/>
<TextBlock Text="{Binding DateMade}" Foreground="{ThemeResource ListViewItemOverlaySecondaryForegroundThemeBrush}" Style="{StaticResource CaptionTextBlockStyle}" TextWrapping="NoWrap" Margin="15,0,15,10"/>
</StackPanel>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
I think another option is to change the DataTemplate dynamically using TemplateSelecting event, on changing content of elements, but it would be a little bit more work.
There might be better solutions though.
Edit
Decided to share some links for the aforementioned idea (Which I've used in WinRT) and another one available in WPF
WPF Based Dynamic DataTemplateSelector - used similar approach in WinRT
DataTemplateSelector - tried slightly modified example and works fine

how to acess on controls inside of stackpanel in windows phone7?

i design page bellow code.
<ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="1" x:Name="svProduct">
<StackPanel>
<ItemsControl x:Name="lstSearchResult" ItemsSource="{Binding Path=PIProductList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Width="480" Style="{Binding CellStyle}" Orientation="Horizontal" VerticalAlignment="Center" Height="50" >
<TextBlock Foreground="Black" FontSize="20" Width="320" FontFamily="Tahoma" Margin="10,0,0,0" Text="{Binding Title}" VerticalAlignment="Center" TextWrapping="Wrap"></TextBlock>
<Button Name="btnBookmark" Click="btnBookmark_Click" Tag="{Binding}" Background="Transparent">
<Button.Content>
<Image Source="/Images/bookmarks_red.png" Width="33" Height="30" VerticalAlignment="Top" Margin="-15"></Image>
</Button.Content>
</Button>
<Button BorderThickness="0" x:Name="btnSubmit" Click="btnSubmit_Click" Background="Transparent" Tag="{Binding}" >
<Button.Content>
<Image Name="ram" Source="/Images/blue_arrow.png" Width="40" Height="40" VerticalAlignment="Top" Margin="-15"></Image>
</Button.Content>
</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</ScrollViewer>
i want to access for btnBookmark visuble false .
can't access btnBookmark.Visibility=Visibility.collapsed
how to do this?
please help to me...........
The best way I know to do this is to create a Visiblity property on your item ViewModel (the one that is bound to each row in your ItemsControl) and toggle that value based on the changes to each item, presumably via the toggle button in each row. I don't know of a good way to "loop and look" for these internal controls. You're much better off using the existing data binding infrastructure to manage this for you.

Categories

Resources