2016-08-28 2 views
0

Ich bin ein Point-of-Sale-System mit WPF bauen und ich habe in eine Mauer gerannt.Bindungsabhängigkeit Eigenschaft zu Viewmodel

Also eine der Komponenten, die ich zu implementieren versuche, ist das "Item Panel" (Canvas), das "Items Buttons" (Button) hostet. In diesem Fenster werden Schaltflächen hinzugefügt, die Elemente darstellen, die im System verwendet werden. Sie können das Bedienfeld sperren/entsperren, um neu erstellte Schaltflächen an den gewünschten Ort zu verschieben.

Ich möchte eine Abhängigkeitseigenschaft für Element Schaltflächen haben, die angeben, ob die Schaltflächen gesperrt sind (oder nicht). Das Erstellen/Sperren/Entsperren von Objektschaltflächen erfolgt über ein Kontextmenü im Objektbereich.

Unten habe ich meinen Code enthalten:

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

Also meine Frage ist, warum ist die Sperre Abhängigkeitseigenschaft in der ItemButton-Ansicht, nicht von der ItemPanel IsLocked-Eigenschaft aktualisiert.

Von meinem Verständnis ist, dass es gebunden sein sollte ... aber nichts scheint aktualisiert zu werden.

Ich würde jede Hilfe sehr schätzen.

Dank

+0

Metadaten zu Abhängigkeitseigenschaften? – Aybe

+0

Entschuldigung, aber ich verstehe Ihren Kommentar nicht? Was meinst du mit Abhängigkeitsdaten-Metadaten? – Firas

+0

http://stackoverflow.com/questions/4182165/dependency-property-is-not-updating-my-usercontrol – Aybe

Antwort

0

verwendete ich MVVM Light für dieses Beispiel.

So haben Sie

  • eine Leinwand mit einem Kontextmenü: etwas hinzufügen, sperren Bewegung
  • Inhalt innerhalb der Leinwand bewegt werden kann, wenn
  • ein einfaches Modell entsperrt, Inhalt kann alles sein, Interaktion wird behandelt
  • ein Vorlagen-Selektor, um Ihren Inhalt eine UI
  • etc. zuzuweisen ...

enter image description here

XAML

<Window x:Class="WpfApplication6.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:local="clr-namespace:WpfApplication6" 
     xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
     mc:Ignorable="d" d:DataContext="{d:DesignInstance local:MyModel}" 
     Title="MainWindow" Height="350" Width="525" x:Name="Window"> 
    <Window.Resources> 
     <local:MyTemplateSelector x:Key="MyTemplateSelector" /> 
     <DataTemplate x:Key="SimpleContentTemplate" DataType="local:SimpleContent"> 
      <Grid Width="200" Height="200" Background="DeepSkyBlue"> 
       <TextBlock Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center"/> 
      </Grid> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <ItemsControl ItemsSource="{Binding Elements}" > 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <Canvas x:Name="Canvas1" IsItemsHost="True" Background="LightBlue"> 
         <Canvas.ContextMenu> 
          <ContextMenu> 
           <MenuItem Header="Add button" Command="{Binding AddButton}" IsEnabled="{Binding IsUnlocked}" /> 
           <MenuItem Header="Lock" IsChecked="{Binding IsLocked}" Command="{Binding Lock}" /> 
          </ContextMenu> 
         </Canvas.ContextMenu> 
        </Canvas> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate > 
        <ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource MyTemplateSelector}"> 
         <i:Interaction.Behaviors> 
          <local:MovableBehavior Canvas="{Binding ElementName=Canvas1}" CanMove="{Binding ElementName=Window, Path=DataContext.IsUnlocked }"/> 
         </i:Interaction.Behaviors> 
        </ContentControl> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </Grid> 
</Window> 

-Code (C# 6)

using System; 
using System.Collections.ObjectModel; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Input; 
using System.Windows.Interactivity; 
using System.Windows.Media; 
using GalaSoft.MvvmLight; 
using GalaSoft.MvvmLight.CommandWpf; 

namespace WpfApplication6 
{ 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new MyModel(); 
     } 
    } 

    public class MyModel : ViewModelBase 
    { 
     private bool _isLocked; 

     public MyModel() 
     { 
      Lock = new RelayCommand(() => 
      { 
       IsLocked = !IsLocked; 
       RaisePropertyChanged(() => IsLocked); 
      }); 

      AddButton = new RelayCommand(() => { Elements.Add(new SimpleContent {Text = "Text"}); }); 

      Elements = new ObservableCollection<object>(); 
     } 

     public ObservableCollection<object> Elements { get; } 

     public RelayCommand Lock { get; } 

     public RelayCommand AddButton { get; } 

     public bool IsUnlocked => !IsLocked; 

     public bool IsLocked 
     { 
      get { return _isLocked; } 
      set 
      { 
       Set(ref _isLocked, value); 
       RaisePropertyChanged(() => IsUnlocked); 
      } 
     } 
    } 

    public class SimpleContent 
    { 
     public string Text { get; set; } 
    } 

    public class MovableBehavior : Behavior<UIElement> 
    { 
     public static readonly DependencyProperty CanvasProperty = DependencyProperty.Register(
      "Canvas", typeof(Canvas), typeof(MovableBehavior), new PropertyMetadata(default(Canvas))); 

     public static readonly DependencyProperty CanMoveProperty = DependencyProperty.Register(
      "CanMove", typeof(bool), typeof(MovableBehavior), new PropertyMetadata(default(bool))); 

     private bool _isDragging; 

     private Point _point; 

     public Canvas Canvas 
     { 
      get { return (Canvas) GetValue(CanvasProperty); } 
      set { SetValue(CanvasProperty, value); } 
     } 

     public bool CanMove 
     { 
      get { return (bool) GetValue(CanMoveProperty); } 
      set { SetValue(CanMoveProperty, value); } 
     } 

     protected override void OnAttached() 
     { 
      AssociatedObject.MouseLeftButtonDown += AssociatedObject_MouseLeftButtonDown; 
      AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp; 
      AssociatedObject.MouseMove += AssociatedObject_MouseMove; 
     } 

     private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      _isDragging = true; 
      _point = e.GetPosition(AssociatedObject); 
      AssociatedObject.CaptureMouse(); 
     } 

     private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) 
     { 
      _isDragging = false; 
      _point = default(Point); 
      AssociatedObject.ReleaseMouseCapture(); 
     } 

     private void AssociatedObject_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (!_isDragging || !CanMove) 
       return; 

      var position = e.GetPosition(Canvas) - _point; 
      var parent = VisualTreeHelper.GetParent(AssociatedObject) as ContentPresenter; 
      if (parent == null) throw new ArgumentNullException(nameof(parent)); 
      Canvas.SetLeft(parent, position.X); 
      Canvas.SetTop(parent, position.Y); 
     } 
    } 

    public class MyTemplateSelector : DataTemplateSelector 
    { 
     public override DataTemplate SelectTemplate(object item, DependencyObject container) 
     { 
      var element = container as FrameworkElement; 
      if (element != null) 
      { 
       if (item is SimpleContent) 
       { 
        return element.FindResource("SimpleContentTemplate") as DataTemplate; 
       } 
      } 

      return null; 
     } 
    } 
} 

Sie haben einige ziemlich Material, das Sie beschäftigt zu halten, ermutige ich Sie zu Schau dir die Dokumentation von Typen an, die ich habe Habe benutzt!

Verwandte Themen