将ObservableCollection中的各个按钮绑定到视图

时间:2016-12-30 19:33:22

标签: wpf data-binding mvvm-light

我在 KeyboardModel 中有一个可观察的按钮集合,如此

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参数(编译器错误)将视图中的键映射到模型中的相应按钮。

继承人的键盘视图

<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灯并简化发布。怎么办呢?

1 个答案:

答案 0 :(得分: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&lt; Key&gt;从您的视图模型:

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; }
}

...并使用带有ItemTemplate的ItemsControl将每个键显示为视图中的Button:

<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>

如评论中所述,按钮等控件仅属于视图。