Make TabItem select first nested button when clicked (WPF MVVM) - wpf

As the title says, I would like the first nested Button to be selected (this button selects a view) when the tab item is clicked. Here is my code below:
<TabItem Header="Scheduling">
<StackPanel Style="{StaticResource ResourceKey=TabStackPanelStyle}">
<RadioButton Command="{Binding BookResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Book</RadioButton>
<RadioButton Command="{Binding NewResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">New</RadioButton>
<RadioButton Command="{Binding EditResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Edit</RadioButton>
<RadioButton Command="{Binding DeleteResourceCommand}" Style="{StaticResource ResourceKey=TabButtonStyle}">Delete</RadioButton>
</StackPanel>
</TabItem>
This TabItem sits in a TabControl with a few more similar TabItems. All I want to do is have the TabItem select the first RadioButton (by default) when it is clicked. These radio buttons change a user control in my ViewModel.
I know it would be possible using EventTriggers associated with the TabItem but there must be a better way.
Thanks!

I think in this situation you can use Binding:
TabItem
<TabItem x:Name="MyTabItem" Header="Two">
<Label Content="Some Content" />
</TabItem>
RadioButton
<RadioButton Name="MyButton" Content="Two" IsChecked="{Binding ElementName=MyTabItem, Path=IsSelected}" />
If you want to be when you click on the RadioButton, the tab is not selected, use Mode=OneWay:
<RadioButton Name="MyButton" IsChecked="{Binding ElementName=MyTabItem, Path=IsSelected, Mode=OneWay}" />

Related

Popup doesn't bind to Toggle when inside DataGrid (xceed)

I've made a Toggle, which expands a Popup window with a ListBox inside. It looks like so:
<ToggleButton Name="Toggle" Height="20" Width="150" >
<StackPanel>
<TextBlock Text="TestListPopup"/>
<Popup Height="200" Width="150"
IsOpen="{Binding ElementName=Toggle, Path=IsChecked}"
PlacementTarget="{Binding ElementName=Toggle}"
HorizontalAlignment="Left"
VerticalAlignment="Bottom">
<ListBox SelectionMode="Multiple" SelectionChanged="TypeSelectionChanged" >
<ListBoxItem Content="Test1"/>
<ListBoxItem Content="Test2"/>
<ListBoxItem Content="Test3"/>
</ListBox>
</Popup>
</StackPanel>
</ToggleButton>
It works perfectly, but I want to use it inside the FilterRow of my xceed DataGrid here:
<xcdg:DataGridControl x:Name="dataGrid"
ItemsSource="{Binding Source={StaticResource DataSource}}">
<xcdg:DataGridControl.View>
<xcdg:TableflowView>
<xcdg:TableflowView.FixedHeaders>
<DataTemplate>
<xcdg:ColumnManagerRow/>
</DataTemplate>
<DataTemplate>
<xcdg:FilterRow>
<xcdg:FilterCell FieldName="Name" IsEnabled="True"/>
<xcdg:FilterCell FieldName="Type" IsEnabled="True">
<!-- TestListPopup control here -->
</xcdg:FilterCell>
</xcdg:FilterRow>
</DataTemplate>
</xcdg:TableflowView.FixedHeaders>
</xcdg:TableflowView>
</xcdg:DataGridControl.View>
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="Name" Title="Name" />
<xcdg:Column FieldName="Type" Title="Type" Width="160"/>
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
In here though, the popup will not bind to the toggle button. Pressing the toggle button doesn't do anything.
I narrowed it down to the binding being broken, because if you set IsOpen="True", it's open (and not adhering to PlacementTarget), but again; it works perfectly outside of the DataGrid..
Why does a perfectly functional control break once put inside the FilterRow?
Any help is appreciated! :)
Why does a perfectly functional control break once put inside the FilterRow?
Because the ToggleButton and the FilterCell don't belong to the same namescope.
You may try to bind using an x:Reference:
IsOpen="{Binding Path=IsChecked, Source={x:Reference Toggle}}"
The other option would be to bind the IsChecked property of the ToggleButton to a bool property of a view model and also bind the IsOpen property of the Popup to the same source property. Make sure that the view model implements the INotifyPropertyChanged interface and raise change notifications when the source property is set.

Click on buttons in DataTemplate - WP8

I'm using this datatemplate for my app , which used context menu from WP8 toolkit . So each item in this datatemplate has a button (to open context menu) and context menu also has click events
So when I use this datatemplate for my LongListSelectors in app, how can I call these click events?
<DataTemplate>
<Grid>
<Grid.ColumnDefenitions>.........
......
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Grid.Column="0"/>
<TextBlock Text="{Binding Artist}" TextWrapping="Wrap" Grid.Column="1"/>
<Button Click="openContext" Grid.Column="2"/>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="false">
<toolkit:MenuItem Header="Download"
Click="context_download" />
<toolkit:MenuItem Header="Add to later"
Click="context_later" />
.......
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
</StackPanel>
</DataTemplate>
Context menu should be declared inside the element and not separately. Declare your context menu inside your button like below code and remove the click event in your button.
Whenever you declare context menu in your button, it works automatically (opens context menu) without any click event.
<Button Content="ContextMenu">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="False">
<toolkit:MenuItem Header="Download" Click="context_download"/>
<toolkit:MenuItem Header="Add to later" Click="context_later"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Button>

Focus movement between list and other elements. WPF

In my window I have the listview and other elements. How I can achieve such behavior of focus: when I press downkey on last listitem focus moves from listview on another element, accordingly pressing upkey on first element moves focus away from list.
So focus on pressing up-downkeys can move from other elements to the list, pass throw the list and leave from the list.
Thanks in advance.
Set the KeyboardNavigation.DirectionalNavigation attached property to Continue. The default for ListBox is Contained.
<ListBox KeyboardNavigation.DirectionalNavigation="Continue"/>
I have different situations in my application. For all controls I have my styles, but in style for the tabcontrol I set property KeyboardNavigation.DirectionalNavigation="Continue".
1. Here should have possibility to be selected listviewitems and tabitems. And when focus on tabitem and I press (->) tabitem changes.
2. Here should have possibility to be selected listboxitems and buttons.
3. Here should have possibility to be selected TabItem and TextBlocks.
And I can use just arrows not tab. 1:
<TabControl Name="tabControl1">
<TabItem Header="PORT" Name="PORT">
<ListView x:Name="ATList"
ItemsSource="{Binding Path=., NotifyOnTargetUpdated=true}"
KeyboardNavigation.DirectionalNavigation="Continue"
KeyUp="ATList_KeyUp" TargetUpdated="ATList_TargetUpdated">
<ListView.View>
<GridView >
<GridViewColumn> ........
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</TabItem>
.......
</TabControl>
2.
<Grid>
<ListBox ItemsSource="{Binding NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
KeyboardNavigation.DirectionalNavigation="Continue"
ClipToBounds="true" TargetUpdated="List_TargetUpdated" SourceUpdated="List_SourceUpdated">
</ListBox>
<WrapPanel>
<Label .../>
<Label .../>
<Button x:Name="NewBtn"
IsEnabled="{Binding ElementName=UsedMemory, Path = Content, Converter={StaticResource RouteNewConverter}}"
Click="NewRouteBtn_Click"> New </Button>
<Button x:Name="DeleteBtn" Click="DeleteBtn_Click"> Delete </Button>
</WrapPanel>
</Grid>
3.
<TabControl Margin="2,5,2,1" Name="tabControl1" >
<TabItem Header="AV" Name="AV">
<Grid>
<StackPanel x:Name="inf">
<TextBlock />
...
<TextBlock />
</StackPanel>
</Grid>
</TabItem>
</TabControl>

Binding visibility to control in different class with WPF

In my main window xaml I have two user controls and two RadioButtons. I want the RadioButtons to control the Visibility of the user controls.
xaml excerpt:
<WpfApp2:ViewTree/>
<WpfApp2:ViewTab/>
<RadioButton x:Name="radioButton_Tree" GroupName="View"
IsChecked="True"> Tree View </RadioButton>
<RadioButton x:Name="radioButton_Tab" GroupName="View"
IsChecked="False" >Tab View</RadioButton>
in the user controls, I have something like this:
Visibility="{Binding IsChecked,
Converter={StaticResource BooleanToVisibilityConverter},
ElementName=Window1.radioButton_Tree}" >
At run time I get this error:
Cannot find source for binding with reference 'ElementName=Window1.radioButton_Tab'
What am I overlooking?
The name Window1 is not in the context of user control.
Can you use the code below?
<WpfApp2:ViewTree Visibility="{Binding IsChecked,
Converter={StaticResource BooleanToVisibilityConverter},
ElementName=radioButton_Tree}" />
<WpfApp2:ViewTab Visibility="{Binding IsChecked,
Converter={StaticResource BooleanToVisibilityConverter},
ElementName=radioButton_Tab}" />
<RadioButton x:Name="radioButton_Tree" GroupName="View"
IsChecked="True"> Tree View </RadioButton>
<RadioButton x:Name="radioButton_Tab" GroupName="View"
IsChecked="False" >Tab View</RadioButton>

WPF ListBoxItem selection problem

I have a listbox where the items contain checkboxes:
<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The problem I'm having is that when I click on the checkbox or its content, the parent ListBoxItem does not get selected. If I click on the white space next to the checkbox, the ListBoxItem does get selected.
The behavior that I'm trying to get is to be able to select one or many items in the list and use the spacebar to toggle the checkboxes on and off.
Some more info:
private void Checkbox_Click(object sender, RoutedEventArgs e)
{
CheckBox chkBox = e.OriginalSource as CheckBox;
}
In the code above when I click on a checkbox, e.Handled is false and chkBox.Parent is null.
Kent's answer put me down the right path, here's what I ended up with:
<ListBox Style="{StaticResource CheckBoxListStyle}" Name="EditListBox" PreviewKeyDown="ListBox_PreviewKeyDown">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" />
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I had to use PreviewKeyDown because by default when you hit the spacebar in a list box, it deselects everything except for the most recently selected item.
To begin with, put the content outside the CheckBox:
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsChecked}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
After that, you will need to ensure that pressing space on a ListBoxItem results in the CheckBox being checked. There are a number of ways of doing this, including a simple event handler on the ListBoxItem. Or you could specify a handler for UIElement.KeyUp or whatever in your DataTemplate:
<CheckBox IsChecked="{Binding IsChecked}" UIElement.KeyUp="..."/>
You can also bind the IsChecked property of the CheckBox and IsSelected property of the ListBoxItem:
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding DisplayText}" IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In your use case it would be way simpler to use a ItemsControl instead of a list box. A ItemsControl is similar to a Listbox except that it doesn't contain the automatic selection behaviour. Which means that using it to host a list of what are essentially checkboxes is very simple and you don't have to workaround the ListBox's selection behaviour.
Simply switching to ItemsControl will give you exactly what you need:
<ItemsControl Style="{StaticResource CheckBoxListStyle}" Name="EditListBox">
<ItemsControl .ItemTemplate>
<DataTemplate>
<CheckBox Click="Checkbox_Click" IsChecked="{Binding Path=IsChecked, Mode=TwoWay}" Content="{Binding Path=DisplayText}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can click on text to check checkboxes (default behavior) and you can use the keyboard too without having to wire up any event handlers.

Resources