Добавить событие клика в массив прямоугольников WPF
Мне нужно добавить событие клика в массив прямоугольников. Я использовал UniformGrid для хранения прямоугольников, и он динамический.
В XAML: <UniformGrid x:Name="GameUniformGrid" HorizontalAlignment="Left" Height="272" VerticalAlignment="Top" Width="272" Grid.Row="0" Grid.Column="0"/>
В C#:
for (int x = 0; x < rowcol; x++)
{
for (int y = 0; y < rowcol; y++)
{
rectangle[y, x] = new Rectangle { Stroke = Brushes.Black, StrokeThickness = 1, Fill = brush };
GameUniformGrid.Children.Add(rectangle[y, x]);
}
}
3 ответа
Прямоугольник не имеет события щелчка. Однако у него есть события MouseDown и MouseUp. Вы можете определить событие MouseDown для своих прямоугольников в UniformGrid следующим образом:
<UniformGrid Rectangle.MouseDown="RectangleClickedEvent" ....../>
В коде позади вы можете иметь свой обработчик событий следующим образом:
private void RectangleClicked(object sender, MouseButtonEventArgs e)
{
var clickedRectangle = e.Source as Rectangle ;
//do something with rectangle. You already have the clicked rectangle here.
//you can even search for this rectangle in your array now or whatever you want.
}
Если вы хотите вместо этого использовать событие click, рассмотрите возможность использования Button, а не прямоугольника, и замените его шаблон элемента управления на прямоугольник. В этом случае вам придется использовать Button.Click вместо присоединенного свойства Rectangle.MouseDown в единой сетке.
<Button>
<Button.Template>
<ControlTemplate>
<Rectangle Width="50" Height="50".../>
</ControlTemplate>
</Button.Template>
</Button>
Однако я до сих пор не уверен, почему вы хотите хранить свои прямоугольники в массиве, поскольку вы всегда будете получать прямоугольник, по которому щелкнули... Пожалуйста, поделитесь тем, что вы пытаетесь сделать, чтобы кто-то мог предложить лучший подход,
Я обнаружил, что обработчик событий не работает, потому что заливки прямоугольников были прозрачными.
Это один из способов реализовать вашу функциональность
(Я использую MVVM - так что никакой код позади и код не создают непосредственно элементы пользовательского интерфейса или устанавливают стиль)
- Добавьте ListView и установите единообразную сетку (или, возможно, Wrap Panel) в качестве ItempsPanelTemplate.
- Свяжите ViewModel с вашим представлением и добавьте наблюдаемую коллекцию, которая будет содержать ваши модели (т.е. дочерние /Rectangle-объекты), с помощью которых вы можете динамически добавлять или удалять элементы в коде, и он будет уведомлять представление об обновлении своего отображения.
- По вашему мнению, вы можете создать шаблон, который будет отображать каждую модель в виде прямоугольника или того, что вы когда-либо могли придумать.
- Наконец добавьте триггер, который будет уведомлять модель представления о том, что она выбрана.
Я знаю, это звучит сложно, но (насколько я знаю), это более тестируемый способ придерживаться лучших практик написания приложений WPF, я могу ошибаться.
Может быть, какой-то код может помочь:
- здесь я использовал Студенты в качестве моделей - вы можете заменить их на класс Rectangles/Images/etc..
Я использую здесь UniformGrid, чтобы ответить на ваш вопрос, но я бы использовал здесь WrapPanel.
<ListView HorizontalContentAlignment="Stretch" ItemsSource="{Binding Students}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" SelectedItem="{Binding SelectedStudent}"> <ListView.ItemsPanel> <ItemsPanelTemplate> <UniformGrid></UniformGrid> </ItemsPanelTemplate> </ListView.ItemsPanel> <ListView.ItemTemplate> <DataTemplate> <Border> <Grid> <Grid.Style> <Style> <Style.Triggers> <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListViewItem}}}" Value="True"> <Setter Property="Grid.Background" Value="#6DB4A0" /> </DataTrigger> </Style.Triggers> </Style> </Grid.Style> <TextBlock Text="{Binding Name}" /> </Grid> </Border> </DataTemplate> </ListView.ItemTemplate> </ListView>
Ваша ViewModel может быть что-то вроде
public class MainViewModel : ViewModelBase
{
private Studetnt _student;
public MainViewModel()
{
Students= new ObservableCollection<Student>(){};
}
public Student SelectedStudent
{
get { return _student; }
set
{
if (_student != value && value != null)
{
_student= value;
}
}
}
public ObservableCollection<Student> Students{ get; set; }
}
Если вы новичок и не понимаете, что я сделал, то сначала я бы предложил вам прочитать о: MVVM/ Templates и Style в WPF/ ObservableCollections в WPF/ Triggers / Binding with RelativeSource В WPF.
Удачи:-)