I use c# .NET 4.5 and WPF RadControls from Telerik.
On my MainWindow I have a RadTabControl and in my code behind I bind my MainViewModel like this:
this.DataContext = new MainViewmodel();
The ItemSource of the RadTabControl is bound in XAML:
<telerik:RadTabControl ... ItemsSourc={Binding Tabs} .. />
I also use a ContentSelector to load different Contents to my Tabs. These Contents are UserControls. On one UserControl I use a RadGRidView with it's own ItemsSource that I bind in the code behind:
TestGridView.ItemsSource = Tasks.GetTasks();
The RadGridView Columns bound to it's own style:
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding ID}" Width="*" CellStyle="{StaticResource CellStyle}" />
</telerik:RadGridView.Columns>
<Style x:Key="CellStyle" TargetType="{x:Type telerik:GridViewCell}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderBrush="#f2f2f2" BorderThickness="0,0,0,2" Padding="0,5,0,5">
<StackPanel Orientation="Horizontal">
<StackPanel Orientation="Vertical" Margin="10,0,0,0" VerticalAlignment="Top">
<TextBlock Text="{Binding Titel}" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Start}" Foreground="#9fa2ae"/>
<TextBlock Text=" XXX - XXX " />
<TextBlock Text="{Binding Startzeit}" Foreground="#9fa2ae" />
<telerik:RadButton Height="30" Content="Right Button" Command="{Binding AddTabCommand}" CommandParameter="Tab9999"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The Problem is that the RadButton does not fire the DelegateCommand of my MainViewModel. I have also the same Button in the UserControl out of the RadGridView, this works fine.
Please can somebody tell me how I can fix this problem of my RadButton in the RadGridView?
Thanks a lot
Best Regards
RR
PS: I have a simple project, but can't attach it
The reason why this is happening is that the binding on your RadButton is trying to find the AddTabCommand on the DataContext of the button, not the parent Window.
To fix this, I would advise setting the style inside the Window's resources, and instead of using this:
Command="{Binding AddTabCommand}"
Give the Window a name, and use this:
Command="{Binding ElementName=windowName, Path=DataContext.AddTabCommand}"
Agree with what Mike said its not finding AddTabCommand in your DataContext(ViewModel).
You can try with specifying whole path of the command :
Command="{Binding ElementName=windowName, Path=NameSapce_Name.ViewModelName.AddTabCommand}".
Related
I am trying to show one collapsed stackpanel on button click, but I'm having problems so I tried reverse my thoughts and I was able to collapse an visible stackpanel. But unfortunately I was unable to implement the behavior I want, show an collapsed stack panel on button click. To the code :D
XAML
<Button x:Name="sentButton" Content="Add Friend" Style="{DynamicResource FlatButtonStyle}" Margin="493,0,0,0" HorizontalAlignment="Left" Width="106"/>
<StackPanel Style="{DynamicResource stackCollapsed}" Visibility="Collapsed">
<Label Content="Invite Friends" FontWeight="Bold" Margin="0,0,477,0" Height="32" />
<StackPanel Orientation="Horizontal" Margin="26,0,0,0">
<Label Content="Enter your friend's email" Width="222" Height="25" />
<TextBox Text="{Binding Email, UpdateSourceTrigger=PropertyChanged}" Style="{DynamicResource MyTextBox}" x:Name="textBoxEmail" Width="298"/>
<Button x:Name="button1" Content="Send" Command="{Binding AddCommand}" Width="77" Style="{DynamicResource FlatButtonStyle}" Margin="20,0,0,0"/>
</StackPanel>
</StackPanel>
Styles
<!-- Style Collapsed-->
<Style x:Key="stackCollapsed" TargetType="StackPanel">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=sentButton,Path=IsPressed}" Value="true">
<Setter Property="StackPanel.Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
Instead of Button use ToggleButton and bind StackPanel.Visibility to ToggleButton.IsChecked property via BooleanToVisibilityConverter converter
<ToggleButton x:Name="sentButton" Content="Add Friend" Margin="493,0,0,0" HorizontalAlignment="Left" Width="106"/>
<StackPanel Visibility="{Binding ElementName=sentButton, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}">
<Label Content="Invite Friends" FontWeight="Bold" Margin="0,0,477,0" Height="32" />
<StackPanel Orientation="Horizontal" Margin="26,0,0,0">
<Label Content="Enter your friend's email" Width="222" Height="25" />
<TextBox Text="{Binding Email, UpdateSourceTrigger=PropertyChanged}" x:Name="textBoxEmail" Width="298"/>
<Button x:Name="button1" Content="Send" Command="{Binding AddCommand}" Width="77" Margin="20,0,0,0"/>
</StackPanel>
</StackPanel>
where converter is defined as below
<Window.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</ResourceDictionary>
</Window.Resources>
The problem is the Visibility property in the <StackPanel> tab takes a higher precedence than anything set in a Style or Trigger, so the Trigger never gets applied. See the Dependency Property Precedence List for more details.
To fix your current solution, move the Visibliity property out of the <StackPanel> tag and into your Style, like this :
<Style x:Key="stackCollapsed" TargetType="StackPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=sentButton,Path=IsPressed}" Value="true">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<StackPanel Style="{DynamicResource stackCollapsed}">
...
</StackPanel>
That said, I would personally recommend something like a Toggle Button with the StackPanel.Visibility bound to the ToggleButton.IsChecked, like this answer suggests.
I solved set the Children to null
stackPanel.Children.Clear();
this work if you need to show / hide the panel the first time, it doesn't work if you need to do runtime
Simple as Stackpanel.Visibility = Visibility.Collapsed.
I have been trying to have a popup whenever I press a button.
However. Lets say that I have a lot of text on that popup and then it can go over the application window bounds.
How I can I tell the popup to keep within the application window bounds in xaml code?
It would be great with some examples in xaml code on how to tell the Popup element to keep within the application
Thanks
Xaml code:
...
<ToggleButton Grid.Row="1" Grid.Column="1" Margin="0,4"
x:Name="Somethingname"
Height="30"
Template="{StaticResource ComboBoxToggleButton}"
Content="Hello man"/>
<Popup Grid.Row="1" Grid.Column="1" x:Name="PopupMe"
Style="{StaticResource PopupStyle}"
ClipToBounds="True">
<TreeView ItemsSource="{Binding SomeObservableCollection}"
Width="{Binding ElementName=DetaljerHjemmmelToggler, Path=ActualWidth}"
ItemTemplate="{StaticResource SomeTemplate}"
cal:Message.Attach="[Event SelectedItemChanged] = [Action TreeView_SelectedItem($this, $source)]">
</TreeView>
</Popup>
...
In ResourceDictionary XAML file:
<HierarchicalDataTemplate x:Key="SomeTemplate" ItemsSource="{Binding ChildrenCollection}">
<TextBlock Text="{Binding Path=TekstBlaaah}" Style="{StaticResource Label}"/>
</HierarchicalDataTemplate>
<Style TargetType="{x:Type Popup}" x:Key="PopupStyle">
<Setter Property="IsOpen" Value="{Binding ElementName=Somethingname, Path=IsChecked}"/>
<Setter Property="AllowsTransparency" Value="True"/>
<Setter Property="PlacementTarget" Value="{Binding ElementName=Somethingname}"/>
<Setter Property="PopupAnimation" Value="Slide"/>
<Setter Property="StaysOpen" Value="False" />
<Setter Property="Placement" Value="Bottom"/>
</Style>
Check it out:
Custom popup and windows in WPF the MVVM way
Sample is also available
I made a Usercontrol with a Combobox with itemTemplate. I set a an event trigger for click on Item. but its not work completely. it dosent accept the click. around the template or empty place before my text.
this is my code
<Combobox>
<Combobox.ItemTemplate>
<DataTemplate>
<Grid Height="25" FlowDirection="RightToLeft">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition MinWidth="100" />
<ColumnDefinition Width="25" />
</Grid.ColumnDefinitions>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<command:EventToCommand Command="{Binding Command}"
CommandParameter="{Binding CommandParameter}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<Image Height="20" Width="25" Grid.Column="0" VerticalAlignment="Center"
HorizontalAlignment="Center" />
<TextBlock Text="{Binding Title}" Grid.Column="1" VerticalAlignment="Center" />
<TextBlock Grid.Column="2" />
</Grid>
</DataTemplate>
</Combobox.ItemTemplate>
</Combobox>
it is a usercontrol that binds to a list of object contains Command and commandparameter, on click on each item one command should be raised.
Visual elements need to be assigned a brush in order for hit testing to take place.
(I did say IsHitTestVisibile so you wouldn't confuse the two).
You can do the following above your ItemTemplate in the Container that hosts it like so :
<ComboBox>
<ComboBox.ItemContainerStyle>
<Style TargetType="ComboBoxItem" BasedOn="{StaticResource {x:Type ComboBoxItem}}"> <!-- Or based on any other ComboboxItem style you have-->
<Setter Property="Background" Value="Transparent" />
</Style>
</ComboBox.ItemContainerStyle>
</ComboBox>
FYI : IsHitTestVisibile is a flag stating that even if a Hit test did pass you can choose to disregard it.
What's wrong with SelectionChanged event of ListBox?
You could bind to that.
DataTemplate is for the data not for UI events. You use data-templates to tell WPF how you want to display data. At most you could have DataTriggers (which is again belong to data).
If you want to trap the click event on items, use ItemContainerStyle. The ItemContainerStyle is for styling the container of dataitem, which is ListBoxItem in this case.
Something of this sort might help:
<Style TargetType="ListBoxItem">
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
</EventTrigger>
</Style.Triggers>
</Style>
I have a ListBox with a DataTemplate. The template has a Button on it. Each item in the list shows the entity.
<ListBox Grid.Column="0"
x:Name="ThemesList"
ItemsSource="{Binding Themes}"
HorizontalAlignment="Left"
VerticalAlignment="Top"
SelectedItem="{Binding SelectedTheme}"
ItemTemplate="{StaticResource ThemeListTemplate}"/>
<DataTemplate x:Key="ThemeListTemplate">
<Grid Grid.Column="1"
Grid.Row="0"
HorizontalAlignment="Right"
Margin="10">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Grid.Row="0"
HorizontalAlignment="Left"
Style="{StaticResource ElementButton}"
Command="{Binding Path=DataContext.ThemeEditorViewModel.OpenThemeEditorCommand, ElementName=ThemesBacklog}"
CommandParameter="{Binding Path=SelectedItem, ElementName=ThemesList}">
<TextBlock Text="Edit"/>
</Button>
<Button Grid.Row="1"
HorizontalAlignment="Left"
Style="{StaticResource ElementButton}"
Command="{Binding Path=DataContext.ThemeDeleteCommand, ElementName=ThemesBacklog}"
CommandParameter="{Binding Path=SelectedItem, ElementName=ThemesList}">
<TextBlock Text="Delete"/>
</Button>
</Grid>
</DataTemplate>
When you click on Button in the command is passed the property value SelectedItem. When you click on ListItem and then click Button - all fine. When I at once click on the Button - in the command is passed null. That is ListItem does not receive focus when you press the button located on this ListItem. How to solve this problem?
You could examine the IsKeyboardFocusWithin property on the ListBoxItems in a trigger, to find out whether a child (like your button), has focus, and set IsSelected to true if that is the case.
You do this by setting the ItemContainerStyle like this:
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
I have ComboBox with custom ItemTemplate.
<ComboBox Height="20" Width="200"
SelectedItem="{Binding Path=SelectedDesign}"
ItemsSource="{Binding Path=Designs}" HorizontalAlignment="Left"
ScrollViewer.CanContentScroll="False">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type formdesign:FormDesignContainer}">
<Rectangle Width="200" Height="100">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Path=ImageThumb}" Stretch="Uniform" />
</Rectangle.Fill>
</Rectangle>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
This works well. However WPF tries to draw rectangle as Combobox Text. How can I set "text" for this template. By "text" I mean string or control which represent selected item and write into combobox when item is selected
In other words I'd like to do this:
But now I got this
Try setting SelectionBoxItemTemplate with a TextBlock.
Appears that SelectionBoxItemTemplate is read-only. So another approach is to override ItemContainerStyle.Template. Example
I found this solution by Ray Burns a good approach. You can define two DataTemplate one for Items in the drop down list and the other for the selected item which should be shown in the Combobox. The using a trigger and checking the visual tree it decide which one to use.
<Window.Resources>
<DataTemplate x:Key="NormalItemTemplate" ...>
...
</DataTemplate>
<DataTemplate x:Key="SelectionBoxTemplate" ...>
...
</DataTemplate>
<DataTemplate x:Key="CombinedTemplate">
<ContentPresenter x:Name="Presenter"
Content="{Binding}"
ContentTemplate="{StaticResource NormalItemTemplate}" />
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding RelativeSource={RelativeSource FindAncestor,ComboBoxItem,1}}"
Value="{x:Null}">
<Setter TargetName="Presenter" Property="ContentTemplate"
Value="{StaticResource SelectionBoxTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</Window.Resources>
...
<ComboBox
ItemTemplate="{StaticResource CombinedTemplate}"
ItemsSource="..."/>
Add Textblock to the datatemplate and bind it
or add Contentpersenter on the rectangle
Edit:
it seems like i didn't got what you were tring to accomplish ,