WFP Databinding dependencies - c#

To summarize before posting my XAML, this form is very simple for now. There is a ListBox, two buttons and a context menu for the ListBox.
If the right mouse button is clicked in the ListBox, and NO ELEMENT is selected, my context menu, performs the ADD operation, which right now is just simply popping up a message box.
When an element is selected, such as MODIFY, my bindings do not work. So I am assuming, after much reading, that I have an inheritance problem somewhere. I have tried using DataContext, RelativeSource, etc...and still no joy.
Here is my XAML
<Window x:Class="FracasReportSettings.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ignore="http://www.ignore.com"
mc:Ignorable="d ignore"
Height="402"
Width="578"
Title="FRACAS Ticket Value Modification"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Skins/MainSkin.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="91*"/>
<ColumnDefinition Width="194*"/>
</Grid.ColumnDefinitions>
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding PageTitle}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" Margin="266,27,10,9" Width="112" Grid.Column="1" />
<StackPanel HorizontalAlignment="Left" Height="311" Margin="40,22,0,0" VerticalAlignment="Top" Width="111">
<Button Content="Detection Method" Margin="10,10,10,10"
Command="{Binding MyBinding}"
CommandParameter="DetectionMethod"/>
<Button Content="Button" Margin="10,0,10,0"/>
</StackPanel>
<ListBox
Name="AdminList"
ItemsSource="{Binding Names}"
Height="302" Width="231" Margin="151,22,0,0"
HorizontalAlignment="Left" VerticalAlignment="Top" Grid.ColumnSpan="2"
SelectedItem="{Binding SomeName}"
>
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="IsSelected" Value="True"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.Resources>
**<-- THIS WORKS FINE -->
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem Header="Add"
Command="{Binding RCContentMenu}">
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>**
<--MY ERROR IS IN HERE-->
**<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext}">
<MenuItem Header="Modify"
Command="{Binding Path=ModifyElementCommand}"
CommandParameter="{Binding Path=SelectedItem}"/>
</ContextMenu>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>**
</ListBox>
</Grid>
The ModifyElementCommand is sitting in a ViewModel named MainViewModel.
The error I receive from the output window is:
System.Windows.Data Error: 4 : Cannot find source for binding with
reference 'RelativeSource FindAncestor,
AncestorType='System.Windows.Controls.ListBox', AncestorLevel='1''.
BindingExpression:Path=DataContext; DataItem=null; target element is
'ContextMenu' (Name=''); target property is 'DataContext' (type
'Object')
Which I know means that the dependency cannot be found.
What should I do to fix this?

Following my comment here is the XAML:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="ContextMenu">
<Setter.Value>
<ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self},Path=PlacementTarget.Tag.DataContext}">
<MenuItem Header="Modify"
Command="{Binding Path=ModifyElementCommand}"
CommandParameter="{Binding Path=SelectedItem}"/>
</ContextMenu>
</Setter.Value>
</Setter>
<Setter Property="Tag" Value="{Binding ElementName=AdminList}" />
</Style>
</ListBox.ItemContainerStyle>

Related

Show ContextMenu of element in ListBox

Problem:
I have a ListBox in which I display my data using DataBinding. The data is displayed as a custom view SystemEnvironmentElementView.
I want to allow the user to rename single elements. This should happen in the ViewModel of the desired element.
I created a ContextMenu in the View that displays my data. However when I right click on my element the ContextMenu is not displayed. I also encountered the problem that on my PreviewMouseDown event handler I don't get the view as OriginalSource in the EventArgs but a Border.
Question:
How do I get the ContextMenu of my element to show?
ListBox Code:
<customControls:ListBoxNoDragSelection ItemsSource="{Binding Elements}" Background="{DynamicResource BG}" SelectedItem="{Binding SystemEnviromentAnalysis.SelectedElement}"
BorderThickness="0" x:Name="ListBoxNoDragSelection" SelectedValue="{Binding SelectedElement}">
<i:Interaction.Behaviors>
<dragAndDrop:FrameworkElementDropBehaviorWithMousePos />
</i:Interaction.Behaviors>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas Background="{DynamicResource MyVisualBrush}"
Height="Auto" Width="Auto" PreviewMouseLeftButtonDown="UIElement_OnPreviewMouseLeftButtonDown"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Canvas.Left" Value="{Binding Element.X}"/>
<Setter Property="Canvas.Top" Value="{Binding Element.Y}"/>
<Setter Property="Canvas.ZIndex" Value="{Binding Element.Z}"/>
<Setter Property="Height" Value="Auto"/>
<Setter Property="Width" Value="Auto"/>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<systemEnvironment:SystemEnvironmentElementView/>
</DataTemplate>
</ListBox.ItemTemplate>
</customControls:ListBoxNoDragSelection>
SystemEnviromentElementView:
<UserControl x:Class="TestApp.Editor.Views.SystemEnvironment.SystemEnvironmentElementView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Height="Auto" Width="Auto">
<UserControl.ContextMenu>
<ContextMenu>
<MenuItem Header="Rename"/>
</ContextMenu>
</UserControl.ContextMenu>
<StackPanel>
<Image Height="{Binding Element.Height}" Width="{Binding Element.Width}" Grid.Row="0" Source="{Binding Element.Icon}" IsHitTestVisible="False"/>
<Label Height="Auto" Width="Auto" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" IsHitTestVisible="False"
Content="{Binding Element.Name}"/>
</StackPanel>

Need help create wpf listview custom control

I want to create a WPF custom control inherit ListView. I know how to build the listview in a normal WPF window but in custom control's Generic.xaml I don't know how to do it.
Can you help me transform the listview below into custom control's Generic.xaml format please?
Thanks.
<ListView x:Name="listView"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"
SelectionMode="Single"
ItemContainerStyle="{DynamicResource MyListViewItemContainerStyle}"
ItemsSource="{TemplateBinding ItemsSource}" >
<ListView.Resources>
<DataTemplate x:Key="FirstColumnDataTemplate" >
<Border BorderBrush="#FFABADB3" BorderThickness="1,0,1,1" Margin="-6,0,-6,0">
<Grid Margin="6,2,6,2">
<ContentPresenter ContentTemplate="{Binding FirstColumnItemTemplate, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CustomControl1}}"
Focusable="False"
RecognizesAccessKey="True"/>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="SecondColumnDataTemplate">
<Border BorderBrush="#FFABADB3" BorderThickness="0,0,1,1" Margin="-6,0,-6,0">
<Grid Margin="6,2,6,2">
<ContentPresenter ContentTemplate="{Binding SecondColumnItemTemplate, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:CustomControl1}}"
Focusable="False"
RecognizesAccessKey="True"/>
</Grid>
</Border>
</DataTemplate>
<Style x:Key="MyListViewItemContainerStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
<Setter Property="Margin" Value="0,-4,0,0"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn x:Name="FirstColumn"
Header="{TemplateBinding FirstColumnHeader}"
CellTemplate="{DynamicResource FirstColumnDataTemplate}"/>
<GridViewColumn x:Name="SecondColumn"
Header="{TemplateBinding SecondColumnHeader}"
CellTemplate="{DynamicResource SecondColumnDataTemplate}"/>
</GridView>
</ListView.View>
</ListView>
FirstColumnHeader, SecondColumnHeader are string dependency properties. FirstColumnItemTemplate, SecondColumnItemTemplate are DataTemplate dependency properties of the custom control.
The custom control itself inherit ListView like:
public class CustomControl1 : ListView

Small clickable area of controls at the edge of the window

I'm using MahApps.Metro 1.3.0 and have a problem with a smaller clickable area of controls at the edge of the window, but if I move them away from the edge of the window the clickable area goes back to normal.
Is there any way to fix this?
My scrollviewer xaml:
<ScrollViewer x:Name="ScrollViewer" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto">
<ItemsControl x:Name="DocumentList" ItemsSource="{Binding Source={StaticResource Documents}}" BorderBrush="{x:Null}" ScrollViewer.CanContentScroll="False" Margin="0,0,0,1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock>
<Hyperlink Command="{Binding DataContext.OpenCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding UNID}">
<InlineUIContainer>
<TextBlock Text="{Binding DisplayName}" />
</InlineUIContainer>
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Expander Header="{Binding Name}" IsExpanded="False">
<ItemsPresenter />
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ItemsControl.GroupStyle>
</ItemsControl>
</ScrollViewer>
And my window xaml:
<Controls:MetroWindow x:Class="MainWindow"
Name="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:data="clr-namespace:System.Windows.Data;assembly=PresentationFramework"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1 0 1 1"
Title="" Height="318" Width="526"
ShowIconOnTitleBar="False"
ResizeMode="NoResize"
Cursor="{Binding Cursor}"
NonActiveWindowTitleBrush="{StaticResource InactiveBlueColorBrush}">

WPF MVVM TreeView item source losing context after command

I have a treeview which contains files, every view model holds an item source which is an ObservableCollection with files items:
public ObservableCollection<CMItemFileNode> SubItemNode
On each item i have context menu options (Delete, Execute..).
If i move from one viewModel to another the ObservableCollection of files updated correctly and presented correctly but, when i perform a context menu command like delete file item, the command execute good but when i move to another view model (which holds SubItemNode ObservableCollection of is own) after the command executed the WPF still thinks i'm in the last view model i was in and not the one i'm really on.
Very important to mention is that when i update to .net 4.5 (which unfortunantly i can't do) everything is ok and the ObservableCollection addresses the correct view model.
Here is the treeView:
<TreeView x:Name="Files" Margin="0,5,5,0" Grid.Row="6" Grid.Column="2" ItemsSource="{Binding SubItemNode}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" Height="300" Grid.RowSpan="6" Width="300" dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDropTarget="True" dd:DragDrop.DropHandler="{Binding}" dd:DragDrop.UseDefaultDragAdorner="True">
<TreeView.Resources>
<Style TargetType="{x:Type TreeView}">
<Setter Property="local:CMTreeViewFilesBehavior.IsTreeViewFilesBehavior" Value="True"/>
</Style>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected}" />
<Setter Property="local:CMTreeViewFilesItemBehavior.IsTreeViewFilesItemBehavior" Value="True"/>
</Style>
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
<SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
</TreeView.Resources>
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem Header="View File" Command="{Binding ExecuteFileCommand}" />
<Separator />
<MenuItem Header="Delete all" Command="{Binding DeleteAllFilesCommand}" />
<MenuItem Header="Delete selected" Command="{Binding DeleteSelectedFilesCommand}" />
</ContextMenu>
</TreeView.ContextMenu>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding SubItemNode}" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Margin="2" Width="32" Height="18" Source="{Binding Path=Icon}" HorizontalAlignment="Left" VerticalAlignment="Center" />
<TextBlock Text="{Binding Path=Name}" Grid.Column="1" Margin="2" VerticalAlignment="Center" Foreground="{Binding Path=Status, Converter={StaticResource ItemFileStatusToColor}}" FontWeight="{Binding Path=IsSelected, Converter={StaticResource BoolToFontWidth}}"/>
</Grid>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
Am I doing somthing wrong? and why in .net 4.5 it works well ?
Apparently in .net 4 after executing a context menu command we lose context inside the tree.
To solve this we need to add this to the context menu:
<ContextMenu DataContext="{Binding PlacementTarget.DataContext, RelativeSource={RelativeSource Self}}" >
If we upgrade to .net 4.5 it's not necessary.

Style importet XAML components

I've got a XAML file with defined resource for a stackpanel. What I would like to do is to style the TextBox in <ResourceProfileViews:DescriptionView/> without affecting other TextBloxes in this view.
My "main" view.
<UserControl x:Class="Comsol.STEA.ProjectViewModule.View.ResourceProfileView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Resources="clr-namespace:Comsol.STEA.Core.Resources;assembly=Core"
xmlns:Converters1="clr-namespace:Comsol.STEA.Core.Utilities.Converters;assembly=Core"
xmlns:Commands="clr-namespace:Comsol.STEA.ProjectViewModule.Commands"
xmlns:ResourceProfileViews="clr-namespace:Comsol.STEA.ProjectViewModule.View.ResourceProfileViews"
xmlns:Behaviors="clr-namespace:WpfLib.Behaviors;assembly=WpfLib"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Resources/Resources.xaml" />
</ResourceDictionary.MergedDictionaries>
<Converters1:BoolToCollapsedVisibilityConverter x:Key="btcvc"/>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel Background="{DynamicResource SteaBackgroundBrush}"
FocusManager.FocusedElement="{Binding ElementName=NameBox}">
<StackPanel.Resources>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Width" Value="360"/>
<Setter Property="MinLines" Value="3"/>
</Style>
</StackPanel.Resources>
<GroupBox Header="{x:Static Resources:Strings.ProfileSettings}">
<StackPanel>
<AdornerDecorator Visibility="{Binding Path=AnyAvailableCategories, Converter={StaticResource btcvc}}">
<StackPanel>
<ResourceProfileViews:DescriptionView/>
</StackPanel>
</AdornerDecorator>
</StackPanel>
</GroupBox>
</StackPanel>
</UserControl>
The DescriptionView
<StackPanel Orientation="Horizontal">
<Label Content="{x:Static Resources:Strings.Description}"/>
<TextBox Text="{Binding Path=Description, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/>
</StackPanel>

Categories

Resources