2016-12-30 2 views
0

У меня есть наблюдаемые коллекции кнопок в KeyboardModel как такBind отдельные кнопки в качестве ObservableCollection в целях

using System.Collections.ObjectModel; 
using System.Windows.Controls; 

namespace SODemo 
{ 
    public class KeyboardModel 
    { 
     public KeyboardModel() 
     { 
      Buttons = new ObservableCollection<Button>(); 
      Buttons.Add(new Button() { Name = "X", Content = "X", IsEnabled = true }); 
      Buttons.Add(new Button() { Name = "Y", Content = "Y", IsEnabled = false}); 
     } 
     public ObservableCollection<Button> Buttons { get; set; } 
    } 
} 

только 2 клавиши должны здесь, но на самом деле это будет полноценная клавиатура и каждый ключ будет находиться в фиксированном положении на экране, как настоящая клавиатура.

Я пытаюсь добиться двухсторонней привязки между каждой кнопкой в ​​модели и соответствующей клавишей на экране, но не могу понять, как это сделать.

В сущности, любая кнопка, включенная в модели, должна быть включена в указанной позиции на экране (CanExecute = true). Как показано в представлении, я не могу использовать параметр Name (ошибка компилятора) для сопоставления ключа в представлении с соответствующей кнопкой в ​​модели.

Heres клавиатура Посмотреть

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SODemo" 
    Height="300" 
    MinWidth="800"> 

    <UserControl.Resources> 
     <local:KeyboardModel x:Key="KeyboardModel" /> 
    </UserControl.Resources> 

    <ItemsControl> 
     <!--   
     <ItemsControl.ItemTemplate> 
       <DataTemplate DataType="Button"> 
        <Button Content="{Binding Path=Does not work}" /> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate>--> 

     <Canvas x:Name="DrawnKeyboard" DataContext="{StaticResource KeyboardModel}" IsEnabled="False"> 

      <!-- this displays first item in collection "X" as expected.. but not what I need--> 
      <Button Canvas.Left="14" Canvas.Top="54" Width="64" Height="50" Content="{Binding Buttons[0]}" Name ="X"> 

      <!--Compiler error "MarkupExtensions are not allowed for Uid or Name property values, so '{Binding Path=Name}' is not valid." --> 
      <Button Canvas.Left="82" Canvas.Top="54" Width="64" Height="50" Name="{Binding Path=Name}"/> 


     </Canvas> 
    </ItemsControl> 
</UserControl> 

Настоящий проект использует MVVM свет и упрощены для размещения. Как это может быть сделано?

+2

Не устанавливайте элементы управления Button в коллекции моделей. Это элементы представления, а не элементы модели. Вместо этого используйте подход ItemTemplate, который вы закомментировали, и создайте класс (view) model, который представляет состояние кнопки. – Clemens

+1

Почему вы смешиваете пользовательский интерфейс и реальную логику? Вы можете определить класс для вашей кнопки, например: public class VirtualButton, который реализует INotifyPropertyChanged и имеет свойства для IsEnabled, Canvas_Top, Canvas_Left, Width, Height, Content. Таким образом, вам не нужно будет отдельно связывать кнопку EACH – bamanow

+0

В свойстве ItemsPanel ItemsControl должен быть объявлен Canvas (или любой другой контейнер, который вы хотите поместить кнопки). – Clemens

ответ

1

Способ сделать это, используя шаблон MVVM бы определить класс модели, которая представляет собой ключ:

public class Key 
{ 
    public string Name { get; set; } 
    public bool IsEnabled { get; set; } 
    public double Left { get; set; } 
    public double Top { get; set; } 
    public double Width { get; set; } 
    public double Height { get; set; } 
} 

... и разоблачить ObservableCollection <Key> из модели вида:

public class KeyboardModel 
{ 
    public KeyboardModel() 
    { 
     Keys = new ObservableCollection<Key>(); 
     Keys.Add(new Key() { Name = "X", IsEnabled = true, Width = 65, Height = 50, Top = 54, Left = 14 }); 
     Keys.Add(new Key() { Name = "Y", IsEnabled = false, Width = 65, Height = 50, Top = 54, Left = 82 }); 
    } 

    public ObservableCollection<Key> Keys { get; set; } 
} 

... и представить каждый ключ в качестве кнопки в представлении, используя ItemsControl с ItemTemplate:

<ItemsControl ItemsSource="{Binding Keys}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas Width="700" Height="700" Background="Yellow" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle> 
     <Style TargetType="ContentPresenter"> 
      <Setter Property="Canvas.Left" Value="{Binding Left}" /> 
      <Setter Property="Canvas.Top" Value="{Binding Top}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate DataType="Button"> 
      <Button Content="{Binding Name}" IsEnabled="{Binding IsEnabled}" 
          Width="{Binding Width}" Height="{Binding Height}"/> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Как указано в комментариях, элементы управления, такие как кнопки, относятся только к виду.

Смежные вопросы