我在ViewModel中使用Custom UserControlViewModel填充了带有ItemControl的Canvas。我想给每个UserControl一个MouseEnter Command或者什么。
我的ViewModel的XAML如下:
<Canvas x:Name="gameFieldCanvas" Width="{Binding CanvasWidth}" Height="{Binding CanvasHeight}">
<ItemsControl ItemsSource="{Binding GameFieldContent}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:GameFieldTileViewModel}">
<Canvas>
<local:GameFieldTileUserControl X="{Binding TileX}" Y="{Binding TileY}">
<local:GameFieldTileUserControl.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding DataContext.OnGameFieldTileLeftClicked, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
<MouseBinding MouseAction="RightClick" Command="{Binding DataContext.OnGameFieldTileRightClicked, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"/>
</local:GameFieldTileUserControl.InputBindings>
</local:GameFieldTileUserControl>
</Canvas>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Canvas>
就像你可以看到我已经为Left- / RightClick命令工作正常。但是MouseEnterEvents没有InputBinding。
我已经读过Blend SDK,你可以在其中编写EventTriggers或类似的内容,但是使用电路板工具是不是可能?
我只想知道在输入UserControl时获取它的UserControlViewModel。
答案 0 :(得分:2)
你能详细介绍一下你最终想要完成什么吗?我可能会为您提供更好的答案,但您可以,我有很多次,覆盖现有控件并添加所需的命令属性。
这是一个具有鼠标移动命令的自定义用户控件。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace WPF_Question_Answer_App
{
public partial class MouseMoveCommandUserControl : UserControl
{
public MouseMoveCommandUserControl()
{
InitializeComponent();
MouseMove += (s, e) =>
{
if (MouseMoveCommand?.CanExecute(MouseMoveCommandParameter) ?? false)
MouseMoveCommand.Execute(MouseMoveCommandParameter);
};
}
public ICommand MouseMoveCommand
{
get => (ICommand)GetValue(MouseMoveCommandProperty);
set => SetValue(MouseMoveCommandProperty, value);
}
public static readonly DependencyProperty MouseMoveCommandProperty =
DependencyProperty.Register(nameof(MouseMoveCommand), typeof(ICommand), typeof(MouseMoveCommandUserControl), new PropertyMetadata(null));
public object MouseMoveCommandParameter
{
get => GetValue(MouseMoveCommandParameterProperty);
set => SetValue(MouseMoveCommandParameterProperty, value);
}
public static readonly DependencyProperty MouseMoveCommandParameterProperty =
DependencyProperty.Register(nameof(MouseMoveCommandParameter), typeof(object), typeof(MouseMoveCommandUserControl), new PropertyMetadata(null));
}
}
并且在视图中使用in是显而易见的。
<Window x:Class="WPF_Question_Answer_App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Question_Answer_App"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MouseMoveCommandUserControl MouseMoveCommand="{Binding SomeMouseMoveCommand}"
MouseMoveCommandParameter="{Binding SomeMouseMoveCommandParameter}"/>
</Grid>
</Window>
希望这有帮助......如果不是,我会删除答案,请告诉我。
答案 1 :(得分:0)
仅举例说明如何使用内置组件实现它。
您可以利用已存在的UI组件来完成大部分目标。有副作用(不能连续两次点击相同的图块,需要修改选择行为的方式等),但这是另一种做事方式。
在窗口中,使用带有适当面板的ListBox。在我的例子中,你可以用它作为tic tac toe游戏的基础:
<Window x:Class="TileClicker.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:TileClicker"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<ListBox
ItemsSource="{Binding Tiles}"
SelectedItem="{Binding SelectedTile}" DisplayMemberPath="Name">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
Rows="3"
Columns="3" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Window>
窗口的代码隐藏是最小的
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
我们的瓷砖由
表示public class Tile : Notifier
{
private string _name = "Click me";
public string Name
{
get
{
return _name;
}
set { _name = value; Notify(); }
}
}
和我们的视图模型使用SelectedItem绑定来了解何时单击一个图块,正确响应
public class ViewModel : Notifier
{
private Tile _tile;
public ObservableCollection<Tile> Tiles { get; } = new ObservableCollection<Tile> {
new Tile(), new Tile(), new Tile(),
new Tile(), new Tile(), new Tile(),
new Tile(), new Tile(), new Tile()
};
public Tile SelectedTile
{
get
{
return _tile;
}
set
{
_tile = value;
Notify();
UpdateName(value);
}
}
private void UpdateName(Tile value)
{
if(value.Name == "Click me")
value.Name = "Woot!";
else
value.Name = "Click me";
}
}
基础只是从上面的类中删除了INPC impl以便于阅读
public class Notifier : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void Notify([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}