Для школы я должен сделать пользовательский интерфейс WPF в С#, код домена уже сделан учителем. мне нужно обрабатывать события щелчка на прямоугольнике, я решил обернуть прямоугольник вокруг кнопки. вот часть моего xaml, где я делаю прямоугольник
<Window x:Class="View.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:ViewModel;assembly=ViewModel"
xmlns:controls="clr-namespace:View.Controls"
mc:Ignorable="d"
x:Name="Picross"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<controls:PiCrossControl x:Name="picrossControl" Margin="0,0,10.2,-0.2" Grid="{Binding Grid}" RowConstraints="{Binding RowConstraints}" ColumnConstraints="{Binding ColumnConstraints}">
<controls:PiCrossControl.SquareTemplate x:Uid="rect">
<DataTemplate>
<Button Command="{Binding Path=DataContext.OnClick, ElementName=Picross}">
<Rectangle IsHitTestVisible="False" Width="40" Height="40" Stroke="Black" Grid.Column="0" StrokeThickness="2">
<Rectangle.Fill>
<Binding Path="Contents.Value">
<Binding.Converter>
<local:SquareConverter Empty="White" Filled="#123456" Unknown="Gray"/>
</Binding.Converter>
</Binding>
</Rectangle.Fill>
</Rectangle>
</Button>
</DataTemplate>
</controls:PiCrossControl.SquareTemplate>
<controls:PiCrossControl.RowConstraintsTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Width="40" Height="40" Text="{Binding Value}" TextAlignment="Center" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</controls:PiCrossControl.RowConstraintsTemplate>
<controls:PiCrossControl.ColumnConstraintsTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Values}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Width="40" Height="40" Text="{Binding Value}" TextAlignment="Center" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</controls:PiCrossControl.ColumnConstraintsTemplate>
</controls:PiCrossControl>
<Button Grid.Column="1" Width="150" Height="20" Command="{Binding CheckSolution}">
<TextBlock Text="check solution"/>
</Button>
</Grid>
Привязка OnClick почему-то не прописывается. вот мой контекст данных xaml
public class GameModel
{
private IPlayablePuzzle PlayablePuzzle;
public GameModel()
{
var puzzle = Puzzle.FromRowStrings("xxxxx", "x...x", "x...x", "x...x", "xxxxx");
var facade = new PiCrossFacade();
this.PlayablePuzzle = facade.CreatePlayablePuzzle(puzzle);
//Console.WriteLine(string.Join("\n", PlayablePuzzle.RowConstraints.Items.Select(x=>x.ToString())));
//var vmGrid = this.PlayablePuzzle.Grid.Map(square => new SquareViewModel(square)).Copy();
this.CheckSolution = new CheckSolution(PlayablePuzzle);
this.OnClick = new OnClick();
}
public IGrid<IPlayablePuzzleSquare> Grid => PlayablePuzzle.Grid;
public IEnumerable<IPlayablePuzzleConstraints> RowConstraints => this.PlayablePuzzle.RowConstraints;
public IEnumerable<IPlayablePuzzleConstraints> ColumnConstraints => this.PlayablePuzzle.ColumnConstraints;
public string Test => "Test";
#region Commands
public ICommand CheckSolution { get; }
public ICommand OnClick { get; }
#endregion
}
Как вы можете видеть, у меня есть 2 контрольных решения ICommands, которые также привязаны к кнопке в моем xaml, и эта кнопка работает (она не обернута вокруг прямоугольника, это просто кнопка, обернутая вокруг текстового блока) ICommand OnClick привязан к моему кнопка прямоугольник. вот мой код OnClick
public class OnClick : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
Console.WriteLine(parameter);
}
}
Обновление: я установил имя окна на пикросс и обновил свою привязку к кнопке, и теперь получаю следующую ошибку: Ошибка System.Windows.Data: 4: не удается найти источник для привязки со ссылкой «Имя элемента = Пикросс». BindingExpression:Path=DataContext.OnClick; Элемент данных = ноль; целевой элемент — «Кнопка» (Name=''); целевое свойство — «Команда» (тип «ICommand»)
1 ответ
Это происходит потому, что команда привязывается из DataTemplate. Вам нужно будет «вернуться» к родителю, чтобы найти контекст данных.
Что-то вроде этого:
Command="{Binding Path=DataContext.OnClick, ElementName=MainWindowName}"
В этом примере я предполагаю, что вы установили GameModel как DataContext окна с именем «MainWindowName».
Таким образом, вы можете добавить свое имя в свое окно следующим образом:
x:Name="MainWindowName"
Вы можете назначить свой контекст данных в конструкторе окна следующим образом:
public MainWindow()
{
InitializeComponent();
DataContext = new GameModel();
}
Это связывание может быть выражено другими способами.
Другой способ сделать это — использовать ссылку следующим образом:
Command="{Binding Path=DataContext.OnClick, Source={x:Reference picrossControl}}"
Похожие вопросы
Связанные вопросы
Новые вопросы
c#
C# (произносится как «see Sharp») — это высокоуровневый мультипарадигменный язык программирования со статической типизацией, разработанный Microsoft. Код C# обычно нацелен на семейство инструментов и сред выполнения Microsoft .NET, которое включает в себя .NET, .NET Framework, .NET MAUI и Xamarin среди прочих. Используйте этот тег для ответов на вопросы о коде, написанном на C#, или о формальной спецификации C#.
GameModel
действительно является контекстомGameModel
. Как вы думаете, почему это не так? Вы проверили окно вывода? Вы установили точку останова вOnClick.Execute
и запустили приложение в режиме отладки?Binding.Elementname
. Это будет работать, еслиDataTemplate
определен в пределах именованного элемента управления.