Wpf 将ObservableCollection中的各个按钮绑定到视图
我在键盘模型中有一组可观察到的按钮,就像这样Wpf 将ObservableCollection中的各个按钮绑定到视图,wpf,data-binding,mvvm-light,Wpf,Data Binding,Mvvm Light,我在键盘模型中有一组可观察到的按钮,就像这样 using System.Collections.ObjectModel; using System.Windows.Controls; namespace SODemo { public class KeyboardModel { public KeyboardModel() { Buttons = new ObservableCollection<Button>
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; }
}
}
使用System.Collections.ObjectModel;
使用System.Windows.Controls;
名称空间SODemo
{
公共类键盘模型
{
公用键盘模型()
{
按钮=新的ObservableCollection();
添加(新按钮(){Name=“X”,Content=“X”,IsEnabled=true});
添加(新按钮(){Name=“Y”,Content=“Y”,IsEnabled=false});
}
公共可观察收集按钮{get;set;}
}
}
这里应该只有两个键,但实际上它将是一个完整的键盘,每个键都将在屏幕上的一个固定位置,就像一个真正的键盘一样
我试图在模型中的每个按钮和屏幕上相应的键之间实现双向绑定,但不知道如何做到这一点
本质上,模型中启用的任何按钮都应在屏幕上的指定位置启用(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 light和simplified进行发布。如何实现这一点?使用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:
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; }
}
公共类键盘模型
{
公用键盘模型()
{
Keys=新的ObservableCollection();
添加(newkey(){Name=“X”,IsEnabled=true,Width=65,Height=50,Top=54,Left=14});
添加(newkey(){Name=“Y”,IsEnabled=false,Width=65,Height=50,Top=54,Left=82});
}
公共ObservableCollection密钥{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>
如注释中所述,按钮等控件仅属于视图。不要将按钮控件放置在视图模型集合中。它们是视图图元,而不是视图模型图元。而是使用您注释掉的ItemTemplate方法,创建一个(视图)模型类来表示按钮的状态?您可以为按钮定义类,例如:公共类VirtualButton,它实现INotifyPropertyChanged,并具有IsEnabled、Canvas_Top、Canvas_Left、Width、Height和Content的属性。因此,这样您就不必单独绑定每个按钮画布(或您希望将按钮放入的任何容器)应该在ItemsControl的ItemsPanel属性中声明。“ItemTemplate方法对我不起作用”。好吧,那就让它工作吧。这就是路。你现在有的是垃圾。。