需要查看我需要添加到列表框的2个不同控件。 控件的类型为IControl
所以我做了以下事情:
Controls.cs
interface IControl
{
double X { get; set; }
double Y { get; set; }
}
class MyButton : Button, IControl, INotifyPropertyChanged
{
public MyButton(string buttonText, double x, double y)
{
this.Content = buttonText;
this.x = x;
this.y = y;
}
private double x = 0;
private double y = 0;
public MyButton()
{
}
public double X
{
get
{ return x;}
set
{
x = value;
OnPropertyChanged("X");
}
}
public double Y
{
get { return y;}
set
{
y = value;
OnPropertyChanged("Y");
}
}
}
class MyLabel : Label, IControl, INotifyPropertyChanged
{
public MyLabel(int number, double x, double y)
{
this.Content = number.ToString(CultureInfo.InvariantCulture);
this.x = x;
this.y = y;
}
private double x = 0;
private double y = 0;
public MyLabel()
{
}
public double X
{
get{ return x;}
set
{
x = value;
OnPropertyChanged("X");
}
}
public double Y
{
get{ return y;}
set
{
y = value;
OnPropertyChanged("Y");
}
}
}
现在在ViewModel.cs中我有
class ViewModel
{
private readonly ObservableCollection<IControl> controls = new ObservableCollection<IControl>();
public ViewModel()
{
var m1 = new MyButton("Test String inside button",0,0);
var m2 = new MyLabel(1123, 0, 80);
controls.Add(m1);
controls.Add(m2);
}
public ObservableCollection<IControl> Controls
{
get {return controls;}
}
}
和我的mainWindow.xaml
<ListBox
x:Name="listBox"
ItemsSource="{Binding Controls}"
SelectionMode="Extended"
>
<ListBox.Resources>
<DataTemplate x:Key="buttonTemplate" DataType="{x:Type local:MyButton}">
<Button Content="{Binding}"
MouseDown="button_MouseDown"
PreviewMouseUp="button_MouseUp"
PreviewMouseMove="button_MouseMove"
/>
</DataTemplate>
<DataTemplate x:Key="labelTemplate" DataType="{x:Type local:MyLabel}">
<Label Content="{Binding}" Background="Aqua"/>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style
TargetType="ListBoxItem"
>
<Setter
Property="Canvas.Left"
Value="{Binding X}"
/>
<Setter
Property="Canvas.Top"
Value="{Binding Y}"
/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
列表框显示我添加到observableCollection的MyButton和MyLabel,但是datatemplates没有做任何事情。 buttonTemplate中的事件未触发,并且未设置标签的背景。
有什么问题? 任何帮助都非常感谢。
提前致谢
答案 0 :(得分:0)
第一个问题。
通常,从Visual
及其后代(如Control
)继承View Model层类型是一个坏主意。在视图模型层中定义视图模型:
// former IControl, renamed to avoid confusing with view layer
public interface ICanvasItem
{
object Content { get; set; }
double X { get; set; }
double Y { get; set; }
}
public class MyButton : ICanvasItem, INotifyPropertyChanged { /* ... */}
public class MyLabel : ICanvasItem, INotifyPropertyChanged { /* ... */}
第二个问题。可以通过三种方式执行项目控件的模板查找:
ItemTemplate
属性。这不是一个选项,因为您需要两个不同的模板; DataTemplateSelector
属性使用ItemTemplateSelector
; 你几乎是第三种方式,但,你的模板有一个密钥,这不允许默认应用模板。要解决此问题,只需丢弃x:Key
属性,并将类型设为模板键:
<ListBox.Resources>
<DataTemplate DataType="{x:Type local:MyButton}">
<Button Content="{Binding Content}"
MouseDown="button_MouseDown"
PreviewMouseUp="button_MouseUp"
PreviewMouseMove="button_MouseMove"
/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MyLabel}">
<Label Content="{Binding Content}" Background="Aqua"/>
</DataTemplate>
</ListBox.Resources>
有关数据模板的更多信息,请参阅此处:http://msdn.microsoft.com/en-us/library/ms742521%28v=vs.110%29.aspx
答案 1 :(得分:-1)
您绑定到IControl的集合,因此您添加到此集合中的任何内容都将被视为IControl,而不是它受尊重的类(MyButton或MyLabel)
因此,在界面上,列表中这些项目的类型是IControl,而不是MyButton或MyLabel,因此不应用样式。
也许您需要重新考虑您的UI设计?