I'm building a Point of Sale system using WPF and I've ran into a brick wall.
So one of the components I'm trying to implement is the "Item Panel" (Canvas) which hosts "Items Buttons" (Button). This panel is used to add buttons which represent items that are used in the system. You can lock/unlock the panel to allow you to move newly created buttons to the location the user pleases.
I want to have a dependency property on Item Buttons that indicate if the buttons are locked (or not). Creating/Locking/unlocking Item Buttons is done by using a context menu in Item Panel.
Below I've included my code:
ItemPanel.xaml
<Window x:Class="ItemPanel.Views.ItemPanelView"
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:ItemPanel"
xmlns:viewModels="clr-namespace:ItemPanel.ViewModels"
xmlns:views="clr-namespace:ItemPanel.Views"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:ItemPanelViewModel, IsDesignTimeCreatable=True}"
Title="ItemPanelView"
Height="800" Width="800">
<ItemsControl ItemsSource="{Binding ItemButtons}">
<!--ItemPanel-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas x:Name="ItemPanel"
Background="LightGray"
ClipToBounds="True"
Focusable="False"
Width="400"
Height="400">
<Canvas.ContextMenu>
<ContextMenu>
<MenuItem Header="Add Item"
Command="{Binding CreateItemButtonCommand}"/>
<MenuItem Header="Lock Panel"
IsCheckable="True"
IsChecked="{Binding IsLocked}"
Command="{Binding LockItemPanelCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}"/>
</ContextMenu>
</Canvas.ContextMenu>
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!--ItemButton-->
<ItemsControl.ItemTemplate>
<DataTemplate>
<views:ItemButtonView x:Name="ItemButton" Lock="{Binding DataContext.IsLocked, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
ItemPanelView.xaml.cs
namespace ItemPanel.Views
{
/// <summary>
/// Interaction logic for ItemPanelView.xaml
/// </summary>
public partial class ItemPanelView : Window
{
public ItemPanelView()
{
InitializeComponent();
DataContext = new ItemPanelViewModel();
}
}
}
ItemPanelViewModel.cs
namespace ItemPanel.ViewModels
{
public class ItemPanelViewModel : ViewModelBase
{
private bool _isLocked;
public ItemPanelViewModel()
{
IsLocked = true;
ItemButtons = new ObservableCollection<ItemButtonViewModel>();
CreateItemButtonCommand = new DelegateCommand(CreateItemButtonCommandHandler);
LockItemPanelCommand = new DelegateCommand<bool?>(LockItemPanelCommandHandler);
}
public ObservableCollection<ItemButtonViewModel> ItemButtons { get; private set; }
#region Create ItemButton
public DelegateCommand CreateItemButtonCommand { get; private set; }
private void CreateItemButtonCommandHandler()
{
//ItemButtonViewModel viewModel = _container.Resolve<ItemButtonViewModel>();
ItemButtonViewModel viewModel = new ItemButtonViewModel() { Label = Guid.NewGuid()};
ItemButtons.Add(viewModel);
}
#endregion
#region Lock ItemPanel
public bool IsLocked
{
get
{
return _isLocked;
}
set
{
_isLocked = value;
OnPropertyChanged("IsLocked");
}
}
public DelegateCommand<bool?> LockItemPanelCommand { get; private set; }
public void LockItemPanelCommandHandler(bool? isChecked)
{
//if (!isChecked.HasValue)
// return;
//foreach (ItemButtonViewModel itemButton in ItemButtons)
//{
//itemButton.IsLocked = IsLocked;
//}
}
#endregion
}
}
ItemButtonView.xaml
<Button x:Class="ItemPanel.Views.ItemButtonView"
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:ItemPanel.Views"
xmlns:viewModels="clr-namespace:ItemPanel.ViewModels"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:ItemButtonViewModel, IsDesignTimeCreatable=True}"
Width="100" Height="100"
Content="{Binding Label}"
ToolTip="{Binding Label}">
</Button>
ItemButtonView.xaml.cs
namespace ItemPanel.Views
{
/// <summary>
/// Interaction logic for ItemButtonView.xaml
/// </summary>
public partial class ItemButtonView : Button
{
public ItemButtonView()
{
InitializeComponent();
}
public static readonly DependencyProperty LockProperty =
DependencyProperty.Register("Lock", typeof(bool), typeof(ItemButtonView));
public bool Lock
{
get { return (bool)GetValue(LockProperty); }
set { SetValue(LockProperty, value); }
}
}
}
ItemButtonViewModel.cs
namespace ItemPanel.ViewModels
{
public class ItemButtonViewModel : ViewModelBase
{
public Guid Label { get; set; }
}
}
So my question is, why is the Lock dependency property in the ItemButton view, not being updated by the ItemPanel IsLocked Property.
From my understanding is that it should be bound... but nothing seems to be getting updated.
I would really appreciate any help given.
Thanks