Unable to call a grid inside a listbox anymore... my xaml is as follows.
<UserControl x:Class="WPFPurpleButtonTest.InstrumentUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFPurpleButtonTest"
mc:Ignorable="d"
d:DesignHeight="750" d:DesignWidth="900">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl x:Name="tabControl" HorizontalAlignment="Left" Height="706" Margin="24,34,0,-212" VerticalAlignment="Top" Width="850" Grid.RowSpan="2">
<TabItem Header="TabItem" Name="mainTab">
<Grid Background="#FFE5E5E5" Margin="0,0,-396,-255">
<Label x:Name="colourName" Content="PURPLE" HorizontalAlignment="Left" Height="93" Margin="284,88,0,0" VerticalAlignment="Top" Width="243" FontWeight="Bold" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" FontSize="50" Foreground="#FFDC00FF"/>
<Button x:Name="testButton" Content="Button" HorizontalAlignment="Left" Margin="365,181,0,0" VerticalAlignment="Top" Width="75" Click="TestButton_Click"/>
<Label x:Name="label" Content="Row Size" HorizontalAlignment="Left" Margin="198,211,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
<Label x:Name="label_Copy" Content="Column Size" HorizontalAlignment="Left" Margin="432,211,0,0" VerticalAlignment="Top" Foreground="#FFDC00FF"/>
<Button x:Name="createGrid" Content="Create Grid" HorizontalAlignment="Left" Margin="365,273,0,0" VerticalAlignment="Top" Width="75" Click="CreateGrid_Click"/>
<TextBox x:Name="rowSizeText" HorizontalAlignment="Left" Height="23" Margin="278,214,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
<TextBox x:Name="columnSizeText" HorizontalAlignment="Left" Height="23" Margin="522,215,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="62"/>
</Grid>
</TabItem>
<TabItem Header="TabItem" Name="gridTab">
<ListBox x:Name="listbox1" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True" Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="20" HorizontalAlignment="Center">
<Viewbox>
<Grid x:Name="wellGrid" Grid.Row="1" ShowGridLines="True"
local:GridHelpers.RowCount="{Binding RowCount}"
local:GridHelpers.ColumnCount="{Binding ColumnCount}" Margin="15,15,15,15" />
</Viewbox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</TabItem>
</TabControl>
</Grid>
</UserControl>
I want to be able to call wellGrid.Children like I used to when the grid was not in a listbox but not entirely sure how to do that now the grid is in the listbox.
The Grid is part of theDataTemplatethat is assigned to theListBoxItem. You need to get theContentPresenterof the item. This is where theDataTemplate` is applied.
private void Button_Click(object sender, RoutedEventArgs e)
{
int selectedItemIndex = this.listbox1.SelectedIndex;
if (selectedItemIndex == -1)
{
return;
}
var itemContainer = this.listbox1.ItemContainerGenerator.ContainerFromIndex(selectedItemIndex) as ListBoxItem;
if (TryFindChildElement(itemContainer, out ContentPresenter contentPresenter))
{
// Get the Grid
var grid = contentPresenter.ContentTemplate.FindName("wellGrid", myContentPresenter) as Grid;
}
}
// Helper to traverse the visual tree
private bool TryFindChildElement<TElement>(DependencyObject parent, out TElement resultElement) where TElement : DependencyObject
{
resultElement = null;
for (var childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(parent); childIndex++)
{
DependencyObject childElement = VisualTreeHelper.GetChild(parent, childIndex);
if (childElement is Popup popup)
{
childElement = popup.Child;
}
if (childElement is TElement)
{
resultElement = childElement as TElement;
return true;
}
if (TryFindChildElement(childElement, out resultElement))
{
return true;
}
}
return false;
}
Related
iam working on desktop wpf MVVM app contain one MainWindow containing content control that make navigation for diffrent UserControls .
commands of the MainViewModel in the MainWindow working well.
but commands of the navigated ViewModels not working.
the code of the app.cs:
navigationStore is the store for the navigated viewModels
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
NavigationStore navigationStore = new NavigationStore();
navigationStore.CurrentViewModel = new MainBackGroundVM();
MainWindow = new MainWindow()
{
///inistiation of the main with passing the CurrentViewModel to the mainVM
DataContext = new MainVM(navigationStore)
};
MainWindow.Show();
base.OnStartup(e);
}
}
the code of MainVM
NavigateUsersCommand working well and navigate for usersVM
class MainVM :Utilities.ViewModelBase
{
private readonly NavigationStore _navigationStore;
public ViewModelBase CurrentViewModel => _navigationStore.CurrentViewModel;
public ICommand NavigateUsersCommand { get; }
public MainVM(NavigationStore navigationStore)
{
_navigationStore = navigationStore;
_navigationStore.CurrentViewModelChanged += _navigationStore_CurrentViewModelChanged;
NavigateUsersCommand = new NavigateUsersCommand(navigationStore);
}
private void _navigationStore_CurrentViewModelChanged()
{
OnPropertyChanged(nameof(CurrentViewModel));
}
}
the code for MainWindow.xml
<Window x:Class="Yakout.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:fa="http://schemas.fontawesome.io/icons/"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:Yakout.ViewModels"
xmlns:v="clr-namespace:Yakout.Views"
xmlns:local="clr-namespace:Yakout"
mc:Ignorable="d"
Title="MainWindow" Height="700" Width="1100" Background="Transparent" AllowsTransparency="True" WindowStartupLocation="CenterScreen" WindowStyle="None" ResizeMode="NoResize" >
<Window.DataContext>
<vm:NavigationVM></vm:NavigationVM>
</Window.DataContext>
<Border BorderThickness="2" BorderBrush="BlueViolet" Background="White">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<Button Style="{StaticResource btnCircle}" Grid.Column="1" Click="Button_Click">
<StackPanel>
<fa:ImageAwesome Icon="Close" Grid.Column="1" Style="{StaticResource close}"/>
</StackPanel >
</Button>
<Border Grid.Row="1" Background="BlueViolet" >
<StackPanel >
<Button Style="{StaticResource btnMainMenu}" Name="btnPOS"
Command="{Binding NavigatePosCommand}">
<StackPanel Style="{StaticResource stack}" Orientation="Horizontal">
<fa:ImageAwesome Icon="ShoppingCart" Style="{StaticResource faMainMenu}" Margin="40 0 0 0"/>
<TextBlock Text="Point Of Sale" Style="{StaticResource tbMainMenu}" Margin="30 10 0 0"/>
</StackPanel>
</Button>
<Button Style="{StaticResource btnMainMenu}" Name="btnSetUp" Command="{Binding NavigateUsersCommand}">
<StackPanel Style="{StaticResource stack}" Orientation="Horizontal" >
<fa:ImageAwesome Icon="Key" Style="{StaticResource faMainMenu}"/>
<TextBlock Text="Set Up" Style="{StaticResource tbMainMenu}"/>
</StackPanel>
</Button>
<Button Style="{StaticResource btnMainMenu}" Name="btnReports"
Command="{Binding NavigateUsersSelectCommand}">
<StackPanel Style="{StaticResource stack}" Orientation="Horizontal">
<fa:ImageAwesome Icon="PencilSquare" Style="{StaticResource faMainMenu}"/>
<TextBlock Text="Reports" Style="{StaticResource tbMainMenu}"/>
</StackPanel>
</Button>
<Button Style="{StaticResource btnMainMenu}" Name="btnOptions"
Command="{Binding NavigateMainBackGroundCommand}" >
<StackPanel Style="{StaticResource stack}" Orientation="Horizontal">
<fa:ImageAwesome Icon="HandPaperOutline" Style="{StaticResource faMainMenu}"/>
<TextBlock Text="Options" Style="{StaticResource tbMainMenu}"/>
</StackPanel>
</Button>
<Button Name="btnLogOut" Style="{StaticResource btnMainMenu}" Margin="5 212 5 0" Click="btnLogOut_Click">
<StackPanel Style="{StaticResource stack}" Orientation="Horizontal">
<fa:ImageAwesome Icon="CircleOutlineNotch" Style="{StaticResource faMainMenu}"/>
<TextBlock Text="Log Out" Style="{StaticResource tbMainMenu}"/>
</StackPanel>
</Button>
</StackPanel>
</Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="/image/R.png"/>
<StackPanel Orientation="Vertical" Grid.Column="1">
<TextBlock Text="Yakout POS" Margin="5 10 5 5" FontSize="25" FontWeight="Bold" HorizontalAlignment="Center"/>
<TextBlock Text="1.0.0.1" FontSize="15" FontWeight="Bold" HorizontalAlignment="Center"/>
<TextBlock Text="Yakout Company" FontSize="15" Foreground="DodgerBlue" FontWeight="Bold" HorizontalAlignment="Center" TextDecorations="Underline"/>
</StackPanel>
</Grid>
<Border Grid.Column="1" Background="BlueViolet">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Canvas>
<Label x:Name="lbl" FontSize="15" Foreground="White" Canvas.Top="10" Canvas.Right="20" Content="{Binding MyTimer}"/>
<TextBlock Text="Point Of Sale" Canvas.Left="250" FontSize="30" Foreground="White" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0 25 0 0"/>
<Ellipse Width="40" Height="40" Fill="DarkViolet" Canvas.Left="150" Canvas.Top="20" StrokeThickness="10"/>
<Ellipse Width="40" Height="40" Fill="DarkViolet" Canvas.Right="230" Canvas.Top="20" StrokeThickness="10"/>
</Canvas>
</Grid>
</Border>
<Rectangle Stroke="BlueViolet" StrokeThickness="3" Grid.Column="0" Grid.Row="0"/>
<ContentControl Content="{Binding CurrentViewModel}" Grid.Row="1" Grid.Column="1" >
</ContentControl>
<!--CurrentView-->
</Grid>
</Border>
the code of the navigated ViewModel , its name UsersVM
the NavigateUsersSelectCommand navigate to new View
and NavigateMainBackGroundCommand navigate back to MainBackGroundView
both commands not working
class UsersVM : Utilities.ViewModelBase
{
public ICommand NavigateUsersSelectCommand { get; }
public ICommand NavigateMainBackGroundCommand { get; }
public UsersVM(NavigationStore navigationStore,SelectedUserStore selectedUserStore)
{
_navigationStore = navigationStore;
NavigateMainBackGroundCommand = new NavigateCommand<MainBackGroundVM>(new NavigationService<MainBackGroundVM>(navigationStore, () => new MainBackGroundVM()));
NavigateUsersSelectCommand = new NavigateCommand<UserSelectVM>(new NavigationService<UserSelectVM>(navigationStore, () => new UserSelectVM(_navigationStore)));
}
}
the xaml code for the usersView
<UserControl x:Class="Yakout.Views.Users"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:fa="http://schemas.fontawesome.io/icons/"
xmlns:local="clr-namespace:Yakout.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Style="{StaticResource user}"
>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.NavigateUsersSelectCommand}">-->
<StackPanel Orientation="Horizontal">
<Button x:Name="select" Style="{StaticResource btnUsers}"
Command="{Binding NavigateUsersSelectCommand}">
<StackPanel>
<fa:ImageAwesome Icon="HandPointerOutline" Style="{StaticResource fa}"/>
<TextBlock Text="Select" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="new" Style="{StaticResource btnUsers}" Click="new_Click">
<StackPanel>
<fa:ImageAwesome Icon="NewspaperOutline" Style="{StaticResource fa}"/>
<TextBlock Text="New" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="save" Style="{StaticResource btnUsers}" Click="save_Click">
<StackPanel>
<fa:ImageAwesome Icon="Save" Style="{StaticResource fa}"/>
<TextBlock Text="Save" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="first" Style="{StaticResource btnUsers}" Click="first_Click">
<StackPanel>
<fa:ImageAwesome Icon="FastBackward" Style="{StaticResource fa}"/>
<TextBlock Text="First" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="back" Style="{StaticResource btnUsers}" Click="back_Click">
<StackPanel>
<fa:ImageAwesome Icon="Backward" Style="{StaticResource fa}"/>
<TextBlock Text="Back" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="next" Style="{StaticResource btnUsers}" Click="next_Click">
<StackPanel>
<fa:ImageAwesome Icon="Forward" Style="{StaticResource fa}"/>
<TextBlock Text="Next" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
<Button x:Name="last" Style="{StaticResource btnUsers}" Click="last_Click">
<StackPanel>
<fa:ImageAwesome Icon="FastForward" Style="{StaticResource fa}"/>
<TextBlock Text="Last" Style="{StaticResource btnText}"/>
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<Label Content="User Name" Style="{StaticResource labelUsers}"/>
<Label Content="Password" Style="{StaticResource labelUsers}"/>
<Label Content="Full Name" Style="{StaticResource labelUsers}"/>
<Label Content="Job Des" Style="{StaticResource labelUsers}"/>
<Label Content="Email" Style="{StaticResource labelUsers}"/>
<Label Content="Phone" Style="{StaticResource labelUsers}"/>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBox Name="tx1" Style="{StaticResource box}" Text="{Binding Path=UserName,Mode=OneWay}"/>
<TextBox Name="tx2" Style="{StaticResource box}" Text="{Binding Path=Password,Mode=OneWay}"/>
<TextBox Name="tx3" Style="{StaticResource box}" Text="{Binding Path=FullName,Mode=OneWay }"/>
<TextBox Name="tx4" Style="{StaticResource box}" Text="{Binding Path=JobDes,Mode=OneWay}"/>
<TextBox Name="tx5" Style="{StaticResource box}" Text="{Binding Path=Email,Mode=OneWay }"/>
<TextBox Name="tx6" Style="{StaticResource box}" Text="{Binding Path=Phone,Mode=OneWay }"/>
</StackPanel>
<Canvas Grid.Column="2">
<Button x:Name="btnBack" Style="{StaticResource btnPages}"
Canvas.Right="5" Canvas.Bottom="5"
Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.NavigateMainBackGroundCommand}">
<StackPanel>
<fa:ImageAwesome Icon="Backward" Style="{StaticResource faPagesBack}"/>
<TextBlock Text="Back" Style="{StaticResource tbPagesBack}"/>
</StackPanel>
</Button>
</Canvas>
</Grid>
</Grid>
the xaml code for the mainBackGroundView
<UserControl x:Class="Yakout.Views.MainBackGround"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Yakout.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Image Source="/image/kkk.jpg" Stretch="Fill"/>
</Grid>
data template for the app
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:Yakout.ViewModels"
xmlns:view="clr-namespace:Yakout.Views">
<DataTemplate DataType="{x:Type vm:OptionsVM}">
<view:Options/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:MainBackGroundVM}">
<view:MainBackGround/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SetUpVM}">
<view:SetUP/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:PosVM}">
<view:Pos/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ReportsVM}">
<view:Reports/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:UsersVM}">
<view:Users/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:UserSelectVM}">
<view:UserSelect/>
</DataTemplate>
code for the app.xml
<Application x:Class="Yakout.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Yakout"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Styles/StylesMainWindow.xaml" />
<ResourceDictionary Source="Styles/StylesMain.xaml" />
<ResourceDictionary Source="Styles/StylesUcOptions.xaml" />
<ResourceDictionary Source="/Utilities/DataTemplate.xaml"/>
<ResourceDictionary Source="/Styles/StylesUsers.xaml"/>
<ResourceDictionary Source="/Styles/StylesUserSelect.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
NavigationService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yakout.Stores;
namespace Yakout.Utilities
{
class NavigationService<TViewModel>
where TViewModel:ViewModelBase
{
private readonly NavigationStore _navigationStore;
private readonly Func<TViewModel> _CreateViewModel;
public NavigationService(NavigationStore navigationStore,Func<TViewModel>CreateViewModel)
{
_navigationStore = navigationStore;
_CreateViewModel = CreateViewModel;
}
public void Navigate()
{
_navigationStore.CurrentViewModel = _CreateViewModel();
}
}
}
ParameterNavigationService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Yakout.Stores;
namespace Yakout.Utilities
{
class ParameterNavigationService<TParameter, TViewModel>
where TViewModel:ViewModelBase
{
private readonly NavigationStore _navigationStore;
private readonly Func<TParameter,TViewModel> _createVM;
public ParameterNavigationService(NavigationStore navigationStore, Func<TParameter, TViewModel> createVM)
{
_navigationStore = navigationStore;
_createVM= createVM;
}
public void Navigate(TParameter parameter)
{
_navigationStore.CurrentViewModel = _createVM(parameter);
}
}
}
NavigateMainBackGroundCommand
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Navigation;
using Yakout.Stores;
using Yakout.Utilities;
using Yakout.ViewModels;
namespace Yakout.Commands
{
class NavigateMainBackGroundCommand : Utilities.CommandBase
{
/// <summary>
/// حاليا مفيش احتياج لاوامر دي
/// </summary>
private readonly NavigationService<MainBackGroundVM> _navigationService;
private readonly MainBackGroundVM _mainBackGroundVM;
public NavigateMainBackGroundCommand(MainBackGroundVM mainBackGroundVM, NavigationService<MainBackGroundVM> navigationService)
{
_navigationService = navigationService;
_mainBackGroundVM = mainBackGroundVM;
}
public override void Execute(object parameter)
{
_navigationService.Navigate();
}
}
}
NavigateUsersCommand
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Yakout.Stores;
using Yakout.ViewModels;
namespace Yakout.Commands
{
class NavigateUsersCommand : Utilities.CommandBase
{
private readonly NavigationStore _navigationStore;
private readonly SelectedUserStore _selectedUserStore;
public NavigateUsersCommand(NavigationStore navigationStore, SelectedUserStore selectedUserStore)
{
_navigationStore = navigationStore;
_selectedUserStore = selectedUserStore;
}
public override void Execute(object parameter)
{
_navigationStore.CurrentViewModel = new UsersVM(_navigationStore,_selectedUserStore);
}
}
}
this is my code on GitHub
github.com/amryakout1990/Yakout.git
i want solution for my problem
Looking at one of these commands you have in your view:
<Button x:Name="select" Style="{StaticResource btnUsers}"
Command="{Binding NavigateUsersSelectCommand}">
In the viewmodel:
NavigateUsersSelectCommand = new NavigateCommand<UserSelectVM>(new NavigationService<UserSelectVM>(navigationStore, () => new UserSelectVM(_navigationStore)));
That expects a command parameter of UserSelectVM type.
You are not passing that because you define no commandparameter in xaml.
Does it even bind? I would have thought there'd be an error in your xaml errors window in vs2022 or the output window.
I guess this is the selected user you want so you could make the commandparameter selecteditem or you could bind selecteditem and reference it in the aonymous method you have there.
But that is why that command does not work.
I didn't look at other commands because there's quite a lot of code to look through. I suggest you fix that one first and see if you have a similar issue repeated.
I have a sample UI and trying to move focus to previous element on pressing Key Up. Can someone help me how to move focus to previous textbox from current Textbox or another elements.
Here is my Sample UI
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:local="clr-namespace:Sample_Application"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel PreviewKeyDown="DockPanel_PreviewKeyDown" PreviewKeyUp="DockPanel_PreviewKeyUp" KeyUp="DockPanel_KeyUp" >
<TextBox DockPanel.Dock="Top" Margin="18,0,0,0" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<TextBox DockPanel.Dock="Top" Margin="18,8,0,0" HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<CheckBox DockPanel.Dock="Top" Margin="18,8,0,0" Content="CheckBox" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<CheckBox DockPanel.Dock="Top" Margin="18,8,0,0" Content="CheckBox" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<RadioButton DockPanel.Dock="Top" Margin="18,8,0,0" Content="RadioButton" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<RadioButton DockPanel.Dock="Top" Margin="18,8,0,0" Content="RadioButton" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<StackPanel>
<TextBox HorizontalAlignment="Left" Margin="153,34,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<TextBox HorizontalAlignment="Left" Margin="153,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
<CheckBox Content="CheckBox" HorizontalAlignment="Left" Margin="153,10,0,0" VerticalAlignment="Top"/>
</StackPanel>
</DockPanel>
</Window>
Below is my code behind
private void DockPanel_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up && e.OriginalSource is TextBox)
{
FocusNavigationDirection focusDirection = FocusNavigationDirection.Previous;
TraversalRequest request = new TraversalRequest(focusDirection);
UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;
// Change keyboard focus.
if (elementWithFocus != null)
{
if (elementWithFocus.MoveFocus(request)) e.Handled = true;
}
e.Handled = true;
}
}
Im using several controls in my main window.
one grid at top that has a list of licenses and i want to display the information of the license each time i change the selection of the grid
MainWindow:
<dx:DXWindow
x:Class="LicenceManagerWPF.Forms.frmCustomerLicense"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
dx:ThemeManager.ThemeName="Office2016"
xmlns:ctr="clr-namespace:LicenceManagerWPF.Controls"
Title="CustomerLicence" Height="800" Width="1000"
WindowStartupLocation="CenterScreen" Loaded="DXWindow_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition MinHeight="200" Height="200*"/>
<RowDefinition Height="200*"/>
<RowDefinition MinHeight="25" Height="25"/>
</Grid.RowDefinitions>
<StackPanel x:Name="Stack_Top" Orientation="Horizontal" Grid.Row="0" >
<dx:SimpleButton x:Name="btnRefresh" Style="{StaticResource ResourceKey=BtnSmall}" ToolTip="Refresh Licenses" Glyph="{dx:DXImage Image=Refresh_32x32.png}" Content="Resfresh" />
<dx:SimpleButton x:Name="btndNew" Style="{StaticResource ResourceKey=BtnSmall}" ToolTip="New License" Glyph="{dx:DXImage Image=New_32x32.png}" Content="New Customer" />
<dx:SimpleButton x:Name="btnDelete" Style="{StaticResource ResourceKey=BtnSmall}" ToolTip="Delete Licence" Content="Delete" Glyph="{dx:DXImage Image=Cancel_32x32.png}"/>
<dx:SimpleButton x:Name="btnEdit" Style="{StaticResource ResourceKey=BtnSmall}" ToolTip="Edit Customer" Glyph="{dx:DXImage Image=EditContact_32x32.png}" />
<TextBlock Text="Customer: " FontSize="20" Margin="5"/>
<TextBlock Text="{Binding Customer.Name}" Margin="5" FontSize="20"/>
</StackPanel>
<ctr:Licences x:Name="grdLicenses" Grid.Row="1">
</ctr:Licences>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ctr:LicenseDetail x:Name="ct_LicenseDetail" Grid.Column="0"/>
<ctr:LicenceLog x:Name="ct_LicenseLog" Grid.Column="1"/>
</Grid>
</Grid>
The grid is ctr_Licenses and the other control is LicenseDetail which should show the information of the license selected, this is the licenseDetail control:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core" x:Class="LicenceManagerWPF.Controls.LicenseDetail"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="600" x:Name="ctrl_LicenseDetail" >
<UserControl.Resources>
<Style x:Key="SmallMargin" TargetType="FrameworkElement">
<Setter Property="Margin" Value="5"/>
</Style>
<Style x:Key="TabMargin" TargetType="FrameworkElement" >
<Setter Property="Margin" Value="2.5"/>
</Style>
<Style x:Key="SmalllMarginTextBlock" BasedOn="{StaticResource SmallMargin}" TargetType="{x:Type TextBlock}">
</Style>
<Style x:Key="SmallMarginDropDown" BasedOn="{StaticResource SmallMargin }" TargetType="dx:DropDownButton" >
</Style>
<Style x:Key="SmallMarginText" BasedOn="{StaticResource SmallMargin}" TargetType="TextBox">
</Style>
<Style x:Key="ckkStyle" TargetType="dxe:CheckEdit" BasedOn="{StaticResource TabMargin}">
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30"/>
<RowDefinition Height="100*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="License Detail" FontSize="16" Grid.ColumnSpan="2" VerticalAlignment="Center" Margin="10" Grid.Row="0" />
<TextBlock Text="Serial Number:" Grid.Column="0" Grid.Row="1" Style="{StaticResource ResourceKey=SmalllMarginTextBlock}"/>
<TextBlock Text="{Binding Path=DataContext.SelectedLicense.SerialNumber, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=Window}}" x:Name="txtSerialNum" Grid.Column="1" Grid.Row="1" Style="{StaticResource ResourceKey=SmalllMarginTextBlock}"/>
<TextBlock Text="Product:" Grid.Column="0" Grid.Row="2" Style="{StaticResource ResourceKey=SmalllMarginTextBlock}" />
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1">
<dx:DropDownButton x:Name="dropDownButton" Width="180" Content="Product" Style="{StaticResource SmallMarginDropDown}">
</dx:DropDownButton>
<TextBlock Text="Status:" Style="{StaticResource SmalllMarginTextBlock}" />
<TextBlock Text="" Width="150" Style="{StaticResource SmalllMarginTextBlock}" />
</StackPanel>
<TextBlock Text="Description:" Style="{StaticResource SmalllMarginTextBlock}" Grid.Row="3" Grid.Column="0" />
<TextBox Text="" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="3" Style="{StaticResource SmallMargin}" Width="350" />
<dx:DXTabControl Grid.Row="4" Grid.ColumnSpan="2">
<dx:DXTabItem x:Name="tabAttributes" Header="License Attributes" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30" />
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="Activation Mode:" Style="{StaticResource TabMargin}" />
<dx:DropDownButton Grid.Row="0" Grid.Column="1" Width="100" HorizontalAlignment="Left" Style="{StaticResource TabMargin}" ButtonKind="Repeat" />
<TextBlock Text="Grace Period:" Style="{StaticResource TabMargin}" Grid.Row="1"/>
<StackPanel Grid.Row="1" Grid.Column="1" Orientation="Horizontal">
<dxe:SpinEdit Width="80" Style="{StaticResource TabMargin}" MinValue="0" MaxValue="100" IsReadOnly="True" Value="10" Mask="n0"/>
<TextBlock Text="Days" Style="{StaticResource TabMargin}" />
</StackPanel>
<dxe:CheckEdit Grid.Row="2" Content="Expiration Date" IsChecked="False" />
<dxe:DateNavigator Grid.Row="2" Grid.Column="1" Width="185" HorizontalAlignment="Left" Style="{StaticResource TabMargin}" />
<TextBlock Text="Max Computers:" Grid.Row="3" Style="{StaticResource TabMargin}"/>
<dxe:SpinEdit Grid.Row="4" Grid.Column="1" HorizontalAlignment="Left" Width="80" Margin="2.5,2.5,2.5,1" MinValue="0" MaxValue="100" IsReadOnly="True" Value="10" Mask="n0"/>
</Grid>
</dx:DXTabItem>
<dx:DXTabItem Header="Product Features" x:Name="tabProductFeatures" Visibility="Visible">
<StackPanel Orientation="Vertical" >
<dxe:CheckEdit Content="Standard" Name="chkStandard" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
<dxe:CheckEdit Content="Admin Mode" Name="chkAdminMode" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
<dxe:CheckEdit Content="Batch Mode" Name="chkBatchMode" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
<dxe:CheckEdit Content="Custom Data Series" Name="chkCustomDataSeries" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
<dxe:CheckEdit Content="Local DataBase" Name="LocalDataBase" IsReadOnly="True" IsChecked="True" Style="{StaticResource ckkStyle}"/>
<dxe:CheckEdit Content="Cloud Data Base" Name="CloudDataBase" Style="{StaticResource ckkStyle}" />
</StackPanel>
</dx:DXTabItem>
<dx:DXTabItem Name="tabComputers" Header="Computers">
<dxg:GridControl Name="grdComputers">
</dxg:GridControl>
</dx:DXTabItem>
<dx:DXTabItem Name="tabMain_Schedule" Header="Maint. Schedule">
<dxg:GridControl>
</dxg:GridControl>
</dx:DXTabItem>
<dx:DXTabItem x:Name="tabFeaturePB" Header="Product Features">
<StackPanel Orientation="Vertical">
<dxe:CheckEdit Content="pb" Name="chkpb" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
<dxe:CheckEdit Content="pb2" Name="chkpb2" IsReadOnly="True" Style="{StaticResource ckkStyle}" />
</StackPanel>
</dx:DXTabItem>
</dx:DXTabControl>
</Grid>
The DataContext class of the mainwindows is this
public class CustomerLicenses
{
private Customer _Customer;
private LicenseList _Licenses;
private License _SelectedLicense;
//private Guid _SelectedSerial;
//public delegate void SelectLicenseEventArg(String SerialNum);
//public event SelectLicenseEventArg SelectLicense;
public CustomerLicenses(Customer Customer)
{
_Customer = Customer;
}
public CustomerLicenses(Customer customer, LicenseList licenses)
{
_Customer = customer;
_Licenses = licenses;
}
public CustomerLicenses()
{
_Customer = new Customer();
_Licenses = new LicenseList();
}
[DataMember]
public Customer Customer
{
get { return _Customer; }
set
{
if (_Customer != value)
{
this._Customer = value;
this.NotifyPropertyChanged("Customer");
}
}
}
[DataMember]
public LicenseList Licenses
{
get { return _Licenses;}
set
{
if (_Licenses != value)
{
this._Licenses = value;
this.NotifyPropertyChanged("Licenses");
}
}
}
private DataTable GetLicensesTable()
{
var dt = new DataTable();
dt.Columns.AddRange(new DataColumn []{
new DataColumn("SerialNumber",typeof(string)),
new DataColumn("Product",typeof(string)),
new DataColumn("Status",typeof(string)),
new DataColumn("ActivationMode",typeof(string)),
new DataColumn("MaxComputers", typeof(int)),
new DataColumn("NumActive",typeof(int)),
new DataColumn("Description",typeof(string)),
new DataColumn("License",typeof(object))
});
_Licenses.ForEach((x) => {
var rw = dt.NewRow();
rw["SerialNumber"] = x.SerialNumber;
rw["Product"] = x.Product.Name;
rw["Status"] = x.Status;
rw["ActivationMode"] = Enum.GetName(typeof(ActivationModeEnum), x.ActivationMode); //x.ActivationMode;
rw["MaxComputers"] = x.MaxComputers;
rw["NumActive"] = Activated(x.Product.ProductId);
rw["Description"] = x.Description;
rw["License"] = x;
dt.Rows.Add(rw);
});
return dt;
}
public DataTable LicensesTable{
get { return GetLicensesTable(); }
}
[DataMember]
public License SelectedLicense {
get { return _SelectedLicense;}
set {
this.NotifyPropertyChanged("SelectedLicense");
_SelectedLicense = value;
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propName)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propName));
}
}
In this part im populating the textblock with the serial, and is ok it shows when i start the app `cause takes the first license but if i select another license the text does not change.
TextBlock Text="{Binding Path=DataContext.SelectedLicense.SerialNumber, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource AncestorType=Window}}" x:Name="txtSerialNum" Grid.Column="1" Grid.Row="1" Style="{StaticResource ResourceKey=SmalllMarginTextBlock}"
This is how i assaing the value when the grid chanege selection
private void GridRowSelected (object sender, SelectedItemChangedEventArgs e)
{
try
{
var Record = (DataRowView)grdLicenses.grdLicences.SelectedItem;
var SelectedLicense = (License)Record["License"];
_CustomerLicense.SelectedLicense = SelectedLicense;
//Customer_Detail.DataContext = SelectedCustomer;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
How can i update the child when the item is selected in the grid.
Regards
sTrenat, as you said i checked the class and i was wrong implementing the propertyfotify
i changed to this
[DataContract]
public class CustomerLicenses: System.ComponentModel.INotifyPropertyChanged
{
public void NotifyPropertyChanged(string propName)
{
System.ComponentModel.PropertyChangedEventHandler handler = PropertyChanged;
if (this.PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propName));
}
}
When the Visibility of ContentPresenter is set to Collapsed and change its Visibility at runtime, breaking the binding of the element kept inside its content.
XAML
<Grid>
<Button x:Name="button"
Width="100"
Height="20"
Margin="173,23,230,268"
Click="button_Click"
Content="Button" />
<ContentPresenter x:Name="contentPresenter"
Margin="0,62,12,0"
Visibility="Collapsed">
<ContentPresenter.Content>
<StackPanel>
<TextBox x:Name="test2"
Width="200"
Height="20" />
<TextBox Width="200"
Height="20"
Text="{Binding ElementName=test2,
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
Code
private void button_Click(object sender, RoutedEventArgs e)
{
if (contentPresenter.IsVisible == false)
{
contentPresenter.Visibility = System.Windows.Visibility.Visible;
}
else if (contentPresenter.IsVisible == true)
{
contentPresenter.Visibility = System.Windows.Visibility.Collapsed;
}
}
Any one help.
if you put your content into a usercontrol your binding will work. if you check your output at runtime you would see that there is a binding error. meaning there is no element with "test2"
<Grid>
<Button x:Name="button"
Width="100"
Height="20"
Margin="173,23,230,268"
Click="button_Click"
Content="Button" />
<ContentPresenter x:Name="contentPresenter"
Margin="0,62,12,0"
Visibility="Collapsed">
<ContentPresenter.Content>
<WpfApplication1:UserControl1/>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
usercontrol
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel>
<TextBox x:Name="test2"
Width="200"
Height="20" />
<TextBox Width="200"
Height="20"
Text="{Binding ElementName=test2,
Path=Text,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</Grid>
</UserControl>
I have created a UserControl name TitleBar, which is placed in every view.
The TitleBar.xaml contains a Button to close the Window in which it contain.
How can i close a Caliburn Window using that Button.
TitleBar UserControl
<UserControl x:Class="JIMS.Controls.TitleBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Style="{StaticResource TitleBar}">
<Rectangle HorizontalAlignment="Stretch" Height="7" Margin="0,0,-5,0" VerticalAlignment="Top" Fill="{DynamicResource DefaultBrush}"></Rectangle>
<Grid HorizontalAlignment="Left" Margin="-10,-5,0,0" Name="Logo">
<TextBlock Name="txtTitle" Style="{StaticResource Title}">JIMS</TextBlock>
<Ellipse HorizontalAlignment="Right" Margin="0,0,5,0" Width="20" Height="20">
<Ellipse.Fill>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_settings_white}" />
</Ellipse.Fill>
</Ellipse>
</Grid>
<Grid HorizontalAlignment="Right">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,5,-4,0">
<Button Name="btnClose" Style="{StaticResource ChromeButtonStyle}" Click="btnClose_Click" IsTabStop="False">
<TextBlock TextWrapping="Wrap" Text="r" FontFamily="Webdings" Foreground="#FF919191" FontSize="13.333" />
</Button>
</StackPanel>
</Grid>
</Grid>
</UserControl>
TitleBar Usage in a View
<UserControl xmlns:my="clr-namespace:JIMS.Controls;assembly=JIMS.Controls" x:Class="JIMS.Views.Stock.UnitView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Name="Unit">
<Border Style="{StaticResource WindowBorderStyle}">
<StackPanel Orientation="Vertical">
<my:TitleBar Title="unit creation"/>
<StackPanel Visibility="{Binding ControlVisiblity}" Orientation="Horizontal" Margin="0,5,0,5">
<StackPanel Orientation="Vertical" Margin="10,0,0,0">
<Label>Short Name :</Label>
<Label>Unit Name :</Label>
</StackPanel>
<StackPanel Orientation="Vertical" Width="200" Margin="0,0,10,0">
<TextBox Name="txtShortName" Text="{Binding Path=UnitShort}"></TextBox>
<TextBox Name="txtUnitName" Text="{Binding Path=UnitName}"></TextBox>
</StackPanel>
</StackPanel>
<Expander Style="{StaticResource DisplayExpander}" IsExpanded="{Binding IsDisplayExpanded}" Header="display units">
<StackPanel Orientation="Horizontal" Margin="0,5,0,5" Visibility="{Binding DisplayVisiblity}">
<DataGrid AutoGenerateColumns="True" Height="200" MinWidth="300" ItemsSource="{Binding Display}"></DataGrid>
</StackPanel>
</Expander>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Name="SaveUnit" Style="{StaticResource MetroButton}">Save</Button>
</StackPanel>
</StackPanel>
</Border>
</UserControl>
In your TitleBar control define a RoutedEvent like this
public event RoutedEventHandler CloseClick
{
add { AddHandler(CloseClickEvent, value); }
remove { RemoveHandler(CloseClickEvent, value); }
}
public static readonly RoutedEvent CloseClickEvent = EventManager.RegisterRoutedEvent(
"CloseClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TitleBar));
void RaiseCloseClickEvent()
{
var newEventArgs = new RoutedEventArgs(TitleBar.CloseClickEvent);
RaiseEvent(newEventArgs);
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
RaiseCloseClickEvent();
}
And attach the btnClose_Click event handler to the btnClose control in your TitleBar
Now, when you use your TitleBar add an action like this
<my:TitleBar Title="This is the title">
<i:Interaction.Triggers>
<i:EventTrigger EventName="CloseClick">
<cal:ActionMessage MethodName="Close"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</my:TitleBar>
This will call the method Close on your viewmodel when the the CloseClickEvent is raised on the TitleBar.
For closing the window, you could derive your viewmodel from Screen and add the following snippet
public void Close()
{
TryClose();
}