Passing Click Events in Composite WPF/XAML Controls - wpf

So, let's say I have a DataTemplate:
<DataTemplate x:Key="ProjectsDataItemTemplate">
<ComboBoxItem x:Name="ProjectComboBox"
Opacity="1" HorizontalAlignment="Stretch"
Foreground="#FF80BBD2"
VerticalAlignment="Center" VerticalContentAlignment="Center"
Background="Transparent"
Style="{DynamicResource ComboBoxItemStyle1}">
<StackPanel>
<Label Content="{Binding Name}" Height="32" VerticalContentAlignment="Top"
FontWeight="Bold" Foreground="#FFFEF9F9" AllowDrop="True" />
<TextBlock Text="{Binding Description}"
Foreground="#FF80BBD2"
Padding="5,0,0,10"
FontStyle="Italic" />
</StackPanel>
</ComboBoxItem>
</DataTemplate>
In this case, the Label and the TextBlock both overlap the clickable area for the ComboBoxItem. How do I ignore and/or pass a click through to the ComboBoxItem when I click one of its child controls?

Just set the IsHitTestVisible property to false for those elements:
<DataTemplate x:Key="ProjectsDataItemTemplate">
<ComboBoxItem x:Name="ProjectComboBox"
Opacity="1"
HorizontalAlignment="Stretch"
Foreground="#FF80BBD2"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Background="Transparent"
Style="{DynamicResource ComboBoxItemStyle1}">
<StackPanel>
<Label IsHitTestVisible="False"
Content="{Binding Name}"
Height="32"
VerticalContentAlignment="Top"
FontWeight="Bold"
Foreground="#FFFEF9F9"
AllowDrop="True" />
<TextBlock IsHitTestVisible="False"
Text="{Binding Description}"
Foreground="#FF80BBD2"
Padding="5,0,0,10"
FontStyle="Italic" />
</StackPanel>
</ComboBoxItem>
</DataTemplate>

Related

How to hide field based on condition check in wpf?

I am trying to hide the Textbox inside the list view based on a condition.
<ListView Margin="0" Name="lvAccessPoints" Background="#ff1d1d1d" Grid.Row="1" BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<iconPacks:PackIconModern Kind="ConnectionWifi" Foreground="White" Width="30" Height="30"/>
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="White" Padding="10,0" FontSize="15" VerticalAlignment="Center"/>
<TextBox HorizontalAlignment="Left"
Height="23"
Margin="10,10,0,0"
TextWrapping="Wrap"
Text=""
VerticalAlignment="Top"
Width="120"
TextChanged="TextBox_TextChanged"
Visibility="{Binding Name!=SelectedItem.Name ? Hidden : Visible}"/>
<Button Click="Button_Click_2"></Button>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I am trying like this , and its not seems to be the right way, what i want is when the particular name in the loop matches the selected items name, then only TextBox should show.
What I am doing wrong?
These kind of expressions are not supported in XAML:
Visibility="{Binding Name!=SelectedItem.Name ? Hidden : Visible}"
What you could do is to define a DataTrigger in your DataTemplate that sets the Visibility property of the TextBox to Visible when the parent ListViewItem is selected:
<ListView Margin="0" Name="lvAccessPoints" Background="#ff1d1d1d" Grid.Row="1" BorderThickness="0">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<iconPacks:PackIconModern Kind="ConnectionWifi" Foreground="White" Width="30" Height="30"/>
<TextBlock Text="{Binding Name}" FontWeight="Bold" Foreground="White" Padding="10,0" FontSize="15" VerticalAlignment="Center"/>
<TextBox HorizontalAlignment="Left"
x:Name="txt"
Height="23"
Margin="10,10,0,0"
TextWrapping="Wrap"
Text=""
VerticalAlignment="Top"
Width="120"
TextChanged="TextBox_TextChanged"
Visibility="Hidden"/>
<Button Click="Button_Click_2"></Button>
</WrapPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}" Value="True">
<Setter TargetName="txt" Property="Visibility" Value="Visible" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Adding Scrollbar to ItemsControl

I have a long list coming from my Business logic which I need to display on the UI. As the list is long, I tried adding Scrollviewer but I am unable to scroll.
please find the XAML code below
<Grid Margin="0,32,0,0">
<TextBlock Text="{Binding IDC_WiFi, Source={StaticResource Resources}}" FontFamily="Segoe UI" FontSize="20" Foreground="#4cb5ab" HorizontalAlignment="Left" />
<Button Command="{Binding HardwareWifiAccordionCommand}" BorderThickness="0" Width="16" HorizontalAlignment="Right" Height="16" >
<Button.Background>
<ImageBrush ImageSource="{Binding AccordionImageHardwareWifi}" />
</Button.Background>
</Button>
</Grid>
<TextBlock Text="Klein's, Anil's" FontFamily="Segoe UI" FontSize="15" Foreground="#8fa3ad"/>
<StackPanel Height="200" Visibility="{Binding IsAccordionHardwareWifi, Converter={StaticResource Bool2Visible}}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding WifiList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,32,0,0">
<Grid>
<Image Source="/Images/Assets/da_wifi1_16x16.png" Height="16" Width="16" HorizontalAlignment="Left" />
<TextBlock Margin="25,0,0,0" Text="{Binding NetworkName}" FontSize="15" Foreground="#FFFFFF" />
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Right" />
</Grid>
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>
Put it into a ScrollViewer.
<ScrollViewer>
<StackPanel >
</StackPanel>
</ScrollViewer>
As #StepUp points out you can just wrap it with a ScrollViewer but I believe this breaks virtualization. That's outside the scope of this question of course but it's something to keep in mind. If performance is likely to become an issue then I'd suggest implementing this as shown in the answer to this question.
The scrollviewer needed a Height to be set
<Grid Margin="0,32,0,0">
<TextBlock Text="{Binding IDC_WiFi, Source={StaticResource Resources}}" FontFamily="Segoe UI" FontSize="20" Foreground="#4cb5ab" HorizontalAlignment="Left" />
<Button Command="{Binding HardwareWifiAccordionCommand}" BorderThickness="0" Width="16" HorizontalAlignment="Right" Height="16" >
<Button.Background>
<ImageBrush ImageSource="{Binding AccordionImageHardwareWifi}" />
</Button.Background>
</Button>
</Grid>
<TextBlock Text="Klein's, Anil's" FontFamily="Segoe UI" FontSize="15" Foreground="#8fa3ad"/>
<StackPanel Height="200" Visibility="{Binding IsAccordionHardwareWifi, Converter={StaticResource Bool2Visible}}">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="350">
<ItemsControl ItemsSource="{Binding WifiList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,32,0,0">
<Grid>
<Image Source="/Images/Assets/da_wifi1_16x16.png" Height="16" Width="16" HorizontalAlignment="Left" />
<TextBlock Margin="25,0,0,0" Text="{Binding NetworkName}" FontSize="15" Foreground="#FFFFFF" />
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Right" />
</Grid>
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>

Can I use a DataTemplate for toolbar buttons and still make the name meaningful?

I have a Toolbar whose ItemSource is a collection of toolbarItems which contain the bitmap text and other info for the button and the xaml includes a DataTemplate to bind the data to the button.
Our app now needs to become 508 compliant and when I run the Accessible Event Watcher it is listing all the toolbar button names as "Unknown".
Can someone tell me how to provide a meaningful name to the buttons?
Here's the portion of xaml applying to this issue:
<ToolBar.ItemTemplate>
<DataTemplate DataType="{x:Type src:toolBarItem}">
<DataTemplate.Resources>
<src:toolBarItemConverter x:Key="buttonConverter" />
<src:booleanToVisibilityConverter x:Key="boolToVisibilityConverter" />
<src:toolBarButtonFormatConverter x:Key="toolBarFormatDisplayConverter" />
<src:stringToVisibilityConverter x:Key="stringToVisibilityDisplayConverter" />
</DataTemplate.Resources>
<StackPanel Orientation="Horizontal">
<Border Style="{StaticResource SeparatorStyle}" Visibility="{Binding menuSeparator, Converter={StaticResource boolToVisibilityConverter}}"/>
<Button x:Name="listButton" Height="{Binding menuHeight, Mode=OneWay}" Width="{Binding menuWidth}" VerticalAlignment="Top" HorizontalAlignment="Center" Visibility="{Binding isActiveButton, Converter={StaticResource boolToVisibilityConverter}}" Tag="{Binding}"
ToolTip="{Binding menuTooltip}" IsEnabled="{Binding isEnabled}" >
<UniformGrid VerticalAlignment="Center" HorizontalAlignment="Center" Rows="{Binding menuText,Converter={StaticResource toolBarFormatDisplayConverter}}" >
<!-- button image -->
<Image Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Source="{Binding menuImage, Converter={StaticResource buttonConverter}}"/>
<!-- button name -->
<Viewbox StretchDirection="DownOnly" HorizontalAlignment="Center" VerticalAlignment="Bottom" Visibility="{Binding menuText, Converter={StaticResource stringToVisibilityDisplayConverter}}" >
<TextBlock x:Name="buttonName" FontFamily="Segoe UI" Width="{Binding menuWidth}" FontSize="12" Grid.Row="1" TextAlignment="Center" TextWrapping="Wrap" HorizontalAlignment="Center" VerticalAlignment="Bottom" Text="{Binding menuText}" Foreground="Black" />
</Viewbox>
</UniformGrid>
<!-- </StackPanel> -->
</Button>
</StackPanel>
</DataTemplate>
</ToolBar.ItemTemplate>
Thanks,
Ron
OK we figured this out. Need to simply bind your names to the AutomationProperties.Name
<Button x:Name="listButton" AutomationProperties.Name="{Binding menuText}"
Height="{Binding menuHeight, Mode=OneWay}" Width="{Binding menuWidth}"
VerticalAlignment="Top" HorizontalAlignment="Center"
Visibility="{Binding isActiveButton,
Converter={StaticResource boolToVisibilityConverter}}"
Tag="{Binding}" ToolTip="{Binding menuTooltip}" IsEnabled="{Binding isEnabled}" >

I unable to get child control from ListBox control in WPF using MVVM

I am in serious trouble. I have listbox control in which i have many combo box. whenever select the value in combo box, i have to make other controls as hidden. i am using MVVM pattren. i am unable to get the child controls from ListBox control but i can get the ListBox control in viewmodel. How can i get these controls in viewmodel? Is it possible? I am using framework 4.0. i have shown the code below which write in view.
<ListBox x:Name="lstItems" MaxHeight="300" FontSize="11" Margin="12,0,20,38" ItemsSource="{Binding Source={StaticResource listedView}, Path=myItemsSource, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}">
<ListBox.ItemTemplate >
<DataTemplate>
<Border BorderBrush="Blue" Margin="0,4,0,4" BorderThickness="1" CornerRadius="5">
<StackPanel Orientation="Horizontal">
<Label Content="Show rules where:" Name="lblshowrules"></Label>
<ComboBox x:Name="cboShowRuleWhere" Height="20" Width="200" ItemsSource="{Binding Source={StaticResource listedView}, Path=FilterRules}" DisplayMemberPath="RuleName" SelectedValuePath="RuleId" SelectedValue="{Binding Source={StaticResource listedView}, Path=SelectedRuleName, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" ></ComboBox>
<Grid Height="29" HorizontalAlignment="Left" Name="grid1" VerticalAlignment="Top" Width="496" Grid.Row="1" Margin="0,0,0,0">
<ComboBox Height="21" HorizontalAlignment="Left" Margin="6,4,0,0" x:Name="cboRuleCondtion" VerticalAlignment="Top" Width="212" />
<TextBox Height="20" HorizontalAlignment="Left" Margin="242,3,0,0" x:Name="txtValue" VerticalAlignment="Top" Width="245" Visibility="Hidden"/>
<ComboBox Height="21" HorizontalAlignment="Left" Margin="224,3,0,0" x:Name="cboValue" VerticalAlignment="Top" Width="205" Visibility="Hidden" />
<DatePicker Height="28" HorizontalAlignment="Left" Margin="242,-3,0,0" x:Name="dtpFromDate" VerticalAlignment="Top" Width="98" Visibility="Hidden" />
<DatePicker Height="31" HorizontalAlignment="Left" Margin="346,-3,0,0" x:Name="dtpToDate" VerticalAlignment="Top" Width="98" Visibility="Hidden"/>
</Grid>
<Button Name="cmdAddLevel" Padding="0" Margin="-1,1,0,-1" Width="75" Command ="{Binding Source={StaticResource listedView}, Path=AddLevelCommand, UpdateSourceTrigger=PropertyChanged}" BorderBrush="White" BorderThickness="1" Height="25" HorizontalContentAlignment="Center">
<StackPanel Orientation="Horizontal">
<Image Height="16" Width="16" HorizontalAlignment="Left" Margin="1,0,0,-1">
</Image>
<TextBlock Text="Add Level" FontWeight="Bold" Height="16" Width="70" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="8,2,0,-1" />
</StackPanel>
</Button>
<Label Name="lblDeleteLevel" Margin="3,0,0,0" Width="75" TabIndex="7" HorizontalAlignment="Left">
<Hyperlink >
<TextBlock Text="Delete Level" />
</Hyperlink>
</Label>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Please help me. once again, i want to know how to get the child control from parent control... Is it possible?
Using the MVVM pattern, you should not be referencing any of the controls directly. Alternatively, you should create a boolean property on your viewmodel that decides if various controls should be visible. Then bind the Visibility property of the controls you want to hide to this property, using a converter.
See this previous Q/A for details on visibility converters: Link

retrieving the content properties from data template in wpf

I have a particular template for a listbox item which contains different textblocks. After adding the items in the listbox I want to retrieve the text of a particular textblock of a particular listbox item. How can I do that?
<ListBox x:Name="listBox1" Grid.Row="0" SelectionChanged="listBox1_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,2,0,0">
<CheckBox Name="cbSelect" VerticalAlignment="Center" Visibility="{Binding isVisible}"/>
<StackPanel Orientation="Vertical">
<Grid HorizontalAlignment="Stretch" >
<TextBlock Name="txtTitle" VerticalAlignment="Bottom" Text="{Binding Title}" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Name="txtDate" Foreground="{StaticResource PhoneInverseInactiveBrush}" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding CreatedOn}" Margin="0,0,30,0" Style="{StaticResource PhoneTextSmallStyle}" />
<!-- <Image x:Name="lineImg" Source="/Icons/appbar.next.rest.png" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="48" Height="48"/>-->
</Grid>
<TextBlock Name="txtContent" Foreground="{StaticResource PhoneDisabledBrush}" VerticalAlignment="Bottom" Text="{Binding Content}" Style="{StaticResource PhoneTextNormalStyle}" />
<Line Stroke="{StaticResource PhoneBorderBrush}" StrokeThickness=" 2" X1="0" Y1="0" X2="{Binding ElementName=listBox1, Path=ActualWidth}" Y2="0" Margin="0,6,0,0" ></Line>
<!-- <Image x:Name="lineImg" Source="/Icons/Line.png" HorizontalAlignment="Center" Width="500" Height="2" Margin="0,15,0,0" />-->
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In the above code, after adding the items to the listbox, I want the text of txtTitle of a particular item. How can I get it?
You need to get a reference to the ContentPresenter of the item.
ListBoxItem myListBoxItem = (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);
The FindVisualChild method along with the full example can be found here.

Resources