I have a slider bound to the volume property of a MediaElement. This works if marked up as below:
<UserControl
x:Class="GenTest.VideoElement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GenTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="600">
<UserControl.Resources>
<Style x:Name="transportStyle" TargetType="Button">
<Setter Property="Height" Value="40" />
<Setter Property="Width" Value="75" />
<Setter Property="FontSize" Value="11" />
</Style>
<Style x:Name="atransportStyle" TargetType="AppBarButton">
<Setter Property="IsCompact" Value="true" />
<Setter Property="FontSize" Value="11" />
</Style>
</UserControl.Resources>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<ContentControl x:Name="videoContainer"
KeyUp="VideoContainer_KeyUp"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Height="400" Grid.Row="0" >
<MediaElement Name="videoMediaElement"
MediaOpened="videoElement_MediaOpened"
MediaEnded="videoMediaElement_MediaEnded"
MediaFailed="videoMediaElement_MediaFailed"
CurrentStateChanged="videoMediaElement_CurrentStateChanged"
AutoPlay="False" />
</ContentControl>
<!-- Transport Controls -->
<StackPanel Name="TransportControlsPanel"
HorizontalAlignment="Center"
Grid.Row="1" >
<Slider Name="timelineSlider" Margin="0,0" Width="500" Height="37"/>
<StackPanel Orientation="Horizontal">
<AppBarButton x:Name="btnPlay" Icon="Play" Click="btnPlay_Click" Style="{StaticResource atransportStyle}" Label="Play"/>
<AppBarButton x:Name="btnStop" Icon="Stop" Click="btnStop_Click" Style="{StaticResource atransportStyle}"/>
<AppBarButton x:Name="btnReverse" Icon="Previous" Click="btnReverse_Click" Style="{StaticResource atransportStyle}"/>
<AppBarButton x:Name="btnForward" Icon="Next" Click="btnForward_Click" Style="{StaticResource atransportStyle}"/>
<Button Name="btnFullScreenToggle" Click="btnFullScreenToggle_Click"
Style="{StaticResource transportStyle}" Content="Full" />
<ComboBox Name="cbAudioTracks"
SelectionChanged="cbAudioTracks_SelectionChanged"
Width="75" />
<AppBarButton x:Name="btnTest" Icon="Other" Style="{StaticResource atransportStyle}">
<AppBarButton.Flyout>
<Flyout>
<StackPanel Orientation="Vertical">
</StackPanel>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
<Slider Minimum="0" Maximum="1" StepFrequency="0.1" Height="100" Value="{Binding Mode=TwoWay,
ElementName=videoMediaElement, Path=Volume}" Orientation="Vertical"/>
</StackPanel>
</StackPanel>
</Grid>
</UserControl>
But when I put the slider into the Flyout the Binding no longer works.
<AppBarButton x:Name="btnTest" Icon="Other" Style="{StaticResource atransportStyle}">
<AppBarButton.Flyout>
<Flyout>
<StackPanel Orientation="Vertical">
<Slider Minimum="0" Maximum="1" StepFrequency="0.1" Height="100" Value="{Binding Mode=TwoWay,
ElementName=videoMediaElement, Path=Volume}" Orientation="Vertical"/>
</StackPanel>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
There are no errors and I cant do a Binding trace because the TraceListeners have been removed from WinRt. I have tried:
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
this.UnhandledException += App_UnhandledException;
DebugSettings.BindingFailed += OnDebugSettingsOnBindingFailed;
}
private void OnDebugSettingsOnBindingFailed(object sender, BindingFailedEventArgs args)
{
new MessageDialog(args.Message).ShowAsync();
}
But no errors are thrown and there is nothing in the output window. In design mode, using the Properties Windows, if i change the volume value of the videoMediaElement then the Value property of the Slider changes but I cant update the Value of the slider, it's read only.
I can make it work within the flyout if I use code:
private void RangeBase_OnValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
var slider = sender as Slider;
videoMediaElement.Volume = slider.Value;
}
but then why bother with bindings at all?
I had this kind of errors some times now, I think that Flyouts are handled separately where the Bindings can't look for the ElementName.
I suggest that you should do this with a ViewModel, instead of cross binding in your Page
Slider.Value [TwoWay-Bind] -> ViewModel.Volume
ViewModel.Volume -> videoMediaElement.Volume
Related
I have the exact same issue as asked in this question. The tabbar changes color when there is content behind it. However, as stated in this question, if they remove the renderer then their problem stops. I currently do not have a renderer at all and still have this problem. The only part of my code that doesn't have this problem are pages that are not in the shell hierarchy and that are navigated to using the following line of code:
var search = new SearchList();
Navigation.PushAsync(search);
The pages that are navigated to using the style of the following lines of code have the tabbar issue:
await Shell.Current.GoToAsync($"//{nameof(MemberList)}");
The xaml and code behind for the different pages are the exact same. The only difference is one is defined in the appshell hierarchy(MemberList) and the other is not(SearchList) as seen below:
<Shell xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SampleYE.Views"
Title="SampleYE"
x:Class="SampleYE.AppShell"
>
<!--
The overall app visual hierarchy is defined here, along with navigation.
https://learn.microsoft.com/xamarin/xamarin-forms/app-fundamentals/shell/
-->
<Shell.Resources>
<ResourceDictionary>
<Style x:Key="BaseStyle" TargetType="Element">
<Setter Property="Shell.BackgroundColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.ForegroundColor" Value="{StaticResource Secondary}" />
<Setter Property="Shell.TitleColor" Value="{StaticResource Secondary}" />
<Setter Property="Shell.DisabledColor" Value="#AD94BB" />
<Setter Property="Shell.UnselectedColor" Value="{StaticResource Tertiary}" />
<Setter Property="Shell.TabBarBackgroundColor" Value="{StaticResource Primary}" />
<Setter Property="Shell.TabBarForegroundColor" Value="{StaticResource Secondary}"/>
<Setter Property="Shell.TabBarUnselectedColor" Value="{StaticResource Tertiary}"/>
<Setter Property="Shell.TabBarTitleColor" Value="{StaticResource Secondary}"/>
</Style>
<Style TargetType="TabBar" BasedOn="{StaticResource BaseStyle}" />
<Style TargetType="FlyoutItem" BasedOn="{StaticResource BaseStyle}" />
</ResourceDictionary>
</Shell.Resources>
<TabBar>
<ShellContent Route="StartupPage" Shell.FlyoutBehavior="Disabled" ContentTemplate="{DataTemplate local:StartupPage}" />
</TabBar>
<TabBar>
<Tab Title="Directory" Icon="icon_feed.png">
<ShellContent Route="MemberList" ContentTemplate="{DataTemplate local:MemberList}"/>
</Tab>
<Tab Title="Profile" Icon="icon_about.png">
<ShellContent Route="ProfilePage1" ContentTemplate="{DataTemplate local:ProfilePage1}" />
</Tab>
</TabBar>
<!--
If you would like to navigate to this content you can do so by calling
await Shell.Current.GoToAsync("//LoginPage");
-->
<TabBar>
<ShellContent Route="LoginPage1" Shell.FlyoutBehavior="Disabled" ContentTemplate="{DataTemplate local:LoginPage1}" />
</TabBar>
</Shell>
The definition of the pages with the issue are as follows:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="SampleYE.Views.MemberList">
<ContentPage.Content>
<ListView x:Name="listView" ItemSelected="OnItemSelected" IsGroupingEnabled="true">
<ListView.GroupHeaderTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="5,0,0,0" VerticalOptions="StartAndExpand" Orientation="Vertical">
<Label Text="{Binding Title}" VerticalTextAlignment="Center" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.GroupHeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal">
<Image WidthRequest="44" HeightRequest="44" Source="{Binding Photo}" />
<StackLayout Padding="5,0,0,0" VerticalOptions="StartAndExpand" Orientation="Vertical">
<Label Text="{Binding Name}" VerticalTextAlignment="Center" Font="Medium" />
<Label Text="{Binding Title}" VerticalTextAlignment="Center" Font="Micro" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
<ContentPage.Content>
<Grid RowDefinitions="Auto">
<ScrollView Grid.Row="0" >
<Grid RowDefinitions="Auto,Auto,Auto,Auto" ColumnDefinitions="*,*" VerticalOptions="CenterAndExpand"
RowSpacing="25">
<Frame Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" BorderColor="{StaticResource Secondary}"
VerticalOptions="Start" HorizontalOptions="Center" WidthRequest="150" HeightRequest="150"
CornerRadius="75" HasShadow="False" Padding="0" IsClippedToBounds="True">
<Image Source="Profile" Aspect="AspectFill"/>
</Frame>
<Button Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
TextColor="{StaticResource Primary}" BackgroundColor="{StaticResource Secondary}"
HeightRequest="54" WidthRequest="54" CornerRadius="27" TranslationX="65"
ImageSource="Camera" HorizontalOptions="Center" VerticalOptions="End"/>
<Frame Grid.Row="2" Grid.ColumnSpan="2" IsClippedToBounds="True"
Margin="20,20,20,0" CornerRadius="15" Padding="0,20,0,20" >
<Grid RowDefinitions="*,*,*" ColumnDefinitions="*,*,*,*" RowSpacing="12" ColumnSpacing="5">
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Calvin"/>
<Label Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Carter"/>
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Ace"/>
<Label Grid.Row="1" Grid.Column="2" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Wrecking Ball"/>
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Spring"/>
<Label Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="2014"/>
</Grid>
</Frame>
<Frame Grid.Row="3" Grid.ColumnSpan="2" IsClippedToBounds="False"
Margin="20,20,20,0" CornerRadius="15" Padding="0,20,0,45" >
<Grid RowDefinitions="*,Auto,Auto,*" ColumnDefinitions="*,*,*,*" RowSpacing="20" ColumnSpacing="5" >
<Label Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" HorizontalTextAlignment="Center"
Text="02/01/1994"/>
<Label Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="4" HorizontalTextAlignment="Center"
Text="Wreckingball14"/>
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="CCC#blackhousedevelopers.com"/>
<Label Grid.Row="2" Grid.Column="2" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Wrecking Ball"/>
<Label Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="Spring"/>
<Label Grid.Row="3" Grid.Column="2" Grid.ColumnSpan="2" HorizontalTextAlignment="Center"
Text="2014"/>
</Grid>
</Frame>
<Grid
Grid.Row="4" Grid.ColumnSpan="2" IsClippedToBounds="False"
Margin="20,0,20,0" Padding="0,20,0,20"
RowDefinitions="Auto,Auto" ColumnDefinitions="*,*" RowSpacing="20" >
<Frame IsClippedToBounds="true" Grid.Row="0" Grid.ColumnSpan="2"
Padding="0"
CornerRadius="15">
<Editor HeightRequest="70" x:Name="interestEntry"
BackgroundColor="{StaticResource Primary}" TextColor="{StaticResource Secondary}"
Placeholder="Interests (i.e. UFC, Fishing, Investing etc;)"
PlaceholderColor="{StaticResource Secondary}"/>
</Frame >
<Frame IsClippedToBounds="true" Grid.Row="1" Grid.ColumnSpan="2"
Padding="0"
CornerRadius="15">
<Editor HeightRequest="140" x:Name="bioEntry"
BackgroundColor="{StaticResource Primary}" TextColor="{StaticResource Secondary}"
Placeholder="Biography (A little information about yourself)"
PlaceholderColor="{StaticResource Secondary}"/>
</Frame>
</Grid>
</Grid>
</ScrollView>
</Grid>
</ContentPage.Content>
The fix to this was updating my ios project to a newer version. they fixed it in the update.
I have my code below, basically to print out an image.
private async void imageControl_PrintButtonClick(object sender, RoutedEventArgs e)
{
var createBitmapTask = Task.Run(async () =>
{
var stream = await provider.OpenEntryAsRandomAccessStreamAsync(currentImageFile);
var decoder = await BitmapDecoder.CreateAsync(stream);
return await decoder.GetSoftwareBitmapAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Premultiplied);
});
var printHelper = new PrintHelper(printPanel);
printHelper.OnPreviewPagesCreated += PrintHelper_OnPreviewPagesCreated;
printPanel.Opacity = 1.0;
var source = new SoftwareBitmapSource();
var bitmap = await createBitmapTask;
await source.SetBitmapAsync(bitmap);
printImage.Source = source;
printFileName.Text = "Hello";
printImage.Height = bitmap.PixelHeight;
printImage.Width = bitmap.PixelWidth;
await printHelper.ShowPrintUIAsync("ZipPicView - " + currentImageFile.ExtractFilename(), true);
printPanel.Opacity = 0;
}
private void PrintHelper_OnPreviewPagesCreated(List<FrameworkElement> obj)
{
ContentDialog dialog = new ContentDialog();
}
However, the print preview shows an empty page. When I print it out, the printer does nothing.
I've tried changing the opacity of the printPanel (which is a Grid object) to non-zero, and the image does display on the screen. Still, the print has nothing on the output page.
I did notice that, on the OnPreviewPagesCreated, its obj parameter has a new object everytime it's called. The first call has one object with both Width and Height as NaN. My guess is because the container has no size, it cannot determine the content size.
Below is the XAML file.
<Page x:Name="page"
x:Class="ZipPicViewUWP.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ZipPicViewUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:behaviors="using:Microsoft.Toolkit.Uwp.UI.Animations.Behaviors"
mc:Ignorable="d" KeyUp="page_KeyUp" Loaded="page_Loaded" SizeChanged="page_SizeChanged">
<Canvas x:Name="canvas" SizeChanged="canvas_SizeChanged">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Height="1019" Width="1920">
<Grid x:Name="printPanel" Opacity="0">
<StackPanel x:Name="printContent"
Margin="0,0"
Orientation="Vertical">
<TextBlock x:Name="printFileName" />
<Image x:Name="printImage"
Stretch="Fill" />
</StackPanel>
</Grid>
<SplitView x:Name="splitView" DisplayMode="CompactOverlay" PanePlacement="Left" CompactPaneLength="50" OpenPaneLength="300">
<SplitView.Content>
<GridView x:Name="thumbnailGrid" />
</SplitView.Content>
<SplitView.Pane>
<Grid Background="{StaticResource SidebarBackground}">
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button x:Name="subFolderButton" Width="50" Height="50" Background="Transparent" Click="subFolderButton_Click">
<SymbolIcon Symbol="List" />
</Button>
<TextBlock VerticalAlignment="Center" Margin="0,15">Folders</TextBlock>
</StackPanel>
<ScrollViewer Grid.Row="1">
<ListView x:Name="subFolderListCtrl" SelectionChanged="subFolderList_SelectionChanged" DataFetchSize="2" Margin="-10,0,0,0" />
</ScrollViewer>
<ProgressRing x:Name="thumbProgress" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Margin="10,0,0,10" />
</Grid>
</SplitView.Pane>
</SplitView>
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="BlurBehavior" Duration="500" AutomaticallyStart="False" />
</interactivity:Interaction.Behaviors>
</Grid>
<Border x:Name="imageBorder" Visibility="Collapsed">
<Image x:Name="image" ManipulationMode="TranslateX" ManipulationCompleted="image_ManipulationCompleted" Tapped="image_Tapped">
<interactivity:Interaction.Behaviors>
<behaviors:Blur x:Name="ImageTransitionBehavior" Duration="500" AutomaticallyStart="False" />
</interactivity:Interaction.Behaviors>
</Image>
</Border>
<local:ViewerControl x:Name="imageControl" Visibility="Collapsed" CloseButtonClick="imageControl_CloseButtonClick" NextButtonClick="imageControl_NextButtonClick" PrevButtonClick="imageControl_PrevButtonClick" SaveButtonClick="imageControl_SaveButtonClick" PrintButtonClick="imageControl_PrintButtonClick" />
<Border x:Name="loadingBorder" Visibility="Collapsed">
<ProgressRing IsActive="True" Width="100" Height="100" />
</Border>
</Canvas>
<Page.TopAppBar>
<CommandBar VerticalContentAlignment="Center" VerticalAlignment="Center">
<CommandBar.Content>
<TextBlock Margin="10,0,0,0" x:Name="filenameTextBlock" Text="<None>" UseLayoutRounding="True" />
</CommandBar.Content>
<AppBarToggleButton x:Name="fullscreenButton" Icon="FullScreen" Label="FullScreen" Checked="fullscreenButton_Checked" Unchecked="fullscreenButton_Unchecked" />
<AppBarSeparator />
<AppBarButton x:Name="openFileButton" Icon="OpenFile" Label="Open File" Click="openFileButton_Click" />
<AppBarButton x:Name="openFolderButton" Icon="Folder" Label="Open Folder" Click="openFolderButton_Click" />
</CommandBar>
</Page.TopAppBar>
</Page>
And the source code is here : https://github.com/wutipong/ZipPicViewCS/tree/master/ZipPicViewUWP
Ok, here is my problem: I have a UserControl Template defined in Style.xaml like this
<Style x:Key="ModulProfTemplate" TargetType="{x:Type UserControl}" >
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type UserControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true" BorderThickness="{TemplateBinding BorderThickness}" DataContext="{Binding DataContext, RelativeSource={RelativeSource TemplatedParent}}">
<Border x:Name="border" BorderBrush="#004E6CA9" BorderThickness="1.5">
<Grid x:Name="Layout" Background="{Binding Background, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="0.5" DataContext="{Binding}">
<Grid.ContextMenu>
<ContextMenu>
<MenuItem Header="Disponibil" Command="{Binding GridContextMenuCommand}" CommandParameter="disp"/>
<MenuItem Header="Indisponibil" Command="{Binding GridContextMenuCommand}" CommandParameter="indisp"/>
</ContextMenu>
</Grid.ContextMenu>
<Grid.RowDefinitions>
<RowDefinition Height="0.497*"/>
<RowDefinition Height="0.5*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" d:LayoutOverrides="Height" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock TextWrapping="Wrap" Text="{Binding SalaSaptPara, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="{Binding MaterieSaptPara, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock TextWrapping="Wrap" Text="{Binding SalaSaptImpara, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<TextBlock TextWrapping="Wrap" Text="{Binding MaterieSaptImpara, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2,0,0,0"/>
</StackPanel>
</Grid>
</Border>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" TargetName="border" Value="#CA4E6CA9"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
the problem is that i don't know how to bind the command to menuitem. The UserControl's DataContext is set to ViewModel.Luni.M1, and the command is in ViewModel DataContext. So my question is: How do i change the DataContext so i can bind the command?
Solved, all i had to do was add a tag to the border that was bound to my viewmodel's datacontext, and after that use PlacementTarget.Tag.MyCommand, as shown like this :)
<Border x:Name="border" BorderBrush="#004E6CA9" BorderThickness="1.5" Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=my:CadreDidacticeView, AncestorLevel=1}, Path=DataContext}">
<Border.ContextMenu>
<ContextMenu>
<MenuItem Header="Disponibil" Command="{Binding PlacementTarget.Tag.GridContextMenuCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}">
</MenuItem>
</ContextMenu>
</Border.ContextMenu>
I have a rather complicated data binding template and I'm not able to find away back to my ViewModel to access a property and command.
This is how my xaml is set up from Top to Bottom as its layout:
<HierarchicalDataTemplate x:Key="ChapterReferencesTemplate">
<StackPanel>
<DockPanel>
<TextBlock Text="Chapter Reference "/>
<AccessText Text="{Binding Path=Chapter}" />
</DockPanel>
<DockPanel>
<TextBlock Text="Total Reference Verses "/>
<AccessText Text="{Binding Path=Verses}" />
</DockPanel>
<ListView Name="VerseReferencesListView" Height="200"
ItemsSource="{Binding Path=VerseReferences}"
SelectedItem="{Binding Path=DataContext.CurrentVerseReference, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type src:CreateWritingsViewModel}}}"
AlternationCount="2"
BorderThickness="0"
IsSynchronizedWithCurrentItem="True">
<ListView.View>
<GridView AllowsColumnReorder="true" ColumnHeaderToolTip="xmlNamespace List" >
<GridViewColumn
Header="Verse"
DisplayMemberBinding="{Binding Path=Verse}" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="Auto" TextAlignment="Left" Text="{Binding}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn
Header="Query"
DisplayMemberBinding="{Binding Path=Query}" Width="Auto">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Width="Auto" TextAlignment="Left" Text="{Binding}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Actions">
<GridViewColumn.CellTemplate>
<DataTemplate>
<Button
Command="{Binding Path=DataContext.LookupReferencesCommand, RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type src:CreateWritingsViewModel}}}"
CommandParameter="{Binding .}"
Template="{StaticResource AddButtonTemplate}" Cursor="Hand" Width="30"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
<HierarchicalDataTemplate x:Key="WritingsReferenceTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200"/>
</Grid.ColumnDefinitions>
<GroupBox Header="{Binding Path=Hebrew}">
<StackPanel Margin="5 10 5 0">
<StackPanel>
<DockPanel>
<TextBlock Text="Writings of "/>
<AccessText Text="{Binding Path=Writings}" />
</DockPanel>
<DockPanel>
<TextBlock Text="Total Reference Chapters : "/>
<AccessText Text="{Binding Path=Chapters}" />
</DockPanel>
<DockPanel>
<TextBlock Text="Total Reference Verses : "/>
<AccessText Text="{Binding Path=Verses}" />
</DockPanel>
<DockPanel >
<TextBlock Text="Query for Writing : "/>
<AccessText Text="{Binding Path=QueryWriting}" />
</DockPanel>
<DockPanel >
<TextBlock Text="Query for Chapters : "/>
<AccessText Text="{Binding Path=QueryChapters}" />
</DockPanel>
</StackPanel>
<DockPanel Margin="0 5 0 0">
<GroupBox Header="Chapter References">
<Expander>
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="200">
<HeaderedItemsControl
ItemTemplate="{StaticResource ChapterReferencesTemplate}"
ItemsSource="{Binding Path=ChapterReferences}"
Margin="10,0,0,0" />
</ScrollViewer>
</Expander>
</GroupBox>
</DockPanel>
</StackPanel>
</GroupBox>
</Grid>
<GroupBox Grid.Column="1" Header="CREATE REFERENCES">
<ListBox
Name="ReferenceListBox"
ItemTemplate="{StaticResource WritingsReferenceTemplate}"
ItemsSource="{Binding Path=odsDocumentsService.WritingsReferenceItems}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VirtualizingStackPanel.IsVirtualizing="False"
VirtualizingStackPanel.VirtualizationMode="Standard">
</ListBox>
In my HierarchicalDataTemplate x:Key="ChapterReferencesTemplate" as you can see I'm already binding to ItemsSource="{Binding Path=VerseReferences}" but I also need to bind to my ViewModel's CurrentVerseReference for the SelectedItem property of the ListView.
Same for my Button Command to my ViewModel's LookupReferencesCommand. All the data is coming from bindings to a object class that contains a ObservableCollection (ChapterReferences, VerseReferences) So far I'm having no success in getting this to work and would appreciate your help very much.
Thanks!...
Well, I found the right properties to use to get this to work. But, I need to do some reading to find out more about these property settings. For my SelectedItem I had to do this:
SelectedItem="{Binding Path=DataContext.CurrentVerseReference, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
And for my Button Command and CommandParameter I had to do this and this is where I need to do more reading to understand how this worked:
<Button Command="{Binding Path=DataContext.LookupReferencesCommand, RelativeSource={RelativeSource AncestorType={x:Type ListBox}, AncestorLevel=2, Mode=FindAncestor}}"
CommandParameter="{Binding Path=DataContext.CurrentVerseReference, RelativeSource={RelativeSource AncestorType={x:Type ListBox}, AncestorLevel=2, Mode=FindAncestor}}"
Template="{StaticResource AddButtonTemplate}" Cursor="Hand" Width="30"/>
Its the AncestorLevel I don't understand. I'm assuming its because I have the Button control at the second level of the ListView?
I would like to highlight a label when the associated textbox has focus. This works:
<Label Grid.Row="1" Grid.Column="0" Target="{Binding ElementName=CountryCode}">
<Label.Style>
<Style TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CountryCode, Path=(IsFocused)}" Value="True">
<Setter Property="Foreground" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
</Label.Style>
<AccessText Text="{Binding Path=CountryCodeLabel}" />
</Label>
<TextBox Grid.Row="1" Grid.Column="1" Name="CountryCode" Text="{Binding Path=CountryCode}" />
But I have a bunch of these textboxes, so I'd prefer to template the style. This works:
<Style x:Key="HighlightOnFocus" TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=CountryCode, Path=(IsFocused)}" Value="True">
<Setter Property="Foreground" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
...
<Label Grid.Row="1" Grid.Column="0" Style="{StaticResource HighlightOnFocus}">
<AccessText Text="{Binding Path=CountryCodeLabel}" />
</Label>
<TextBox Grid.Row="1" Grid.Column="1" Name="CountryCode" Text="{Binding Path=CountryCode}" />
but of course I can't hard code the ElementName in there. So I tried this:
<Style x:Key="HighlightOnFocus" TargetType="{x:Type Label}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(IsFocused)}" Value="True">
<Setter Property="Foreground" Value="Blue" />
</DataTrigger>
</Style.Triggers>
</Style>
...
<Label Grid.Row="1" Grid.Column="0" Style="{StaticResource HighlightOnFocus}" DataContext="{Binding ElementName=CountryCode}">
<AccessText Text="{Binding Path=CountryCodeLabel}" />
</Label>
<TextBox Grid.Row="1" Grid.Column="1" Name="CountryCode" Text="{Binding Path=CountryCode}" />
But setting the DataContext in the label messes up the binding in my AccessText element. So the question is - is there a way specify the element name for the style datatrigger in some way other than setting the datacontext? Is there a better way to accomplish what I'm trying to do?
There is a nice solution over here:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/627e4d27-351b-4e2d-86a3-9367af3f0edf/how-to-set-a-label-style-when-the-target-textbox-has-focus?forum=wpf
In general, it's fairly easy. Create a custom attached property like this:
public static class CustomAttached
{
public static readonly DependencyProperty IsTargetFocusedProperty = DependencyProperty.RegisterAttached(
"IsTargetFocused", typeof(bool), typeof(CustomAttached),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsTargetFocused(UIElement element, bool value)
{
element.SetValue(IsTargetFocusedProperty, value);
}
public static bool GetIsTargetFocused(UIElement element)
{
return (bool)element.GetValue(IsTargetFocusedProperty);
}
}
Then add a style for the highlighting:
<Window.Resources>
<Style x:Key="HighlightOnFocus" TargetType="{x:Type Label}">
<Style.Triggers>
<Trigger Property="local:CustomAttached.IsTargetFocused" Value="True">
<Setter Property="Background" Value="CadetBlue" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
And then simply use it like that:
<Label Content="Label" Style="{StaticResource HighlightOnFocus}"
local:CustomAttached.IsTargetFocused="{Binding IsFocused, ElementName=textBox}">
</Label>
<TextBox x:Name="textBox" Text="TextBox" />