Прямоугольник, завернутый в кнопку, не запускает команду - PullRequest
0 голосов
/ 01 апреля 2020

Для школы я должен сделать пользовательский интерфейс WPF в c# код домена уже сделан учителем. Я должен обрабатывать события щелчка на прямоугольнике, я решил обернуть прямоугольник вокруг кнопки. Вот часть моего 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 по какой-то причине не регистрируется. вот мой datacontext из 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);
    }
}

: я установил имя окна на picross, обновил привязку для кнопки и теперь получаю следующую ошибку: System. Windows .Data Error: 4: Cannot найти источник для привязки со ссылкой «ElementName = Picross». BindingExpression: Path = DataContext.OnClick; DataItem = NULL; Целевым элементом является «Кнопка» (Имя = ''); целевое свойство 'Command' (тип 'ICommand')

1 Ответ

0 голосов
/ 01 апреля 2020

Это происходит потому, что команда привязана из шаблона данных. Вам нужно будет «вернуться» к родителю, чтобы найти контекст данных.

Примерно так:

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}}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...