Как я могу использовать функцию C# для доступа к элементу управления WPF, который ее вызвал?

Я работаю над редактором игрового уровня в WPF с использованием C#.

У меня есть ряд элементов управления изображением для выбора текстур, и я хочу, чтобы каждое изображение было кликабельным, с некоторыми видимыми отзывами, чтобы показать, какая из них выбрана.

Вот один из элементов управления изображением вместе с зеленой рамкой выделения, которая появляется при нажатии:

<Image x:Name="tile_image1" Source="as asphalt_test.png" Stretch="Fill" HorizontalAlignment="Right" VerticalAlignment="Top" Width="50" Height="50" MouseDown="texture_click" Margin="0,93,69,0" RenderTransformOrigin="0.16,2.04"/>
<Border x:Name="tile_border" BorderBrush="Lime" BorderThickness="3" HorizontalAlignment="Right" Height="54" Margin="0,91,65,0" VerticalAlignment="Top" Width="54" Visibility="Hidden" />

Мой вопрос касается функции "texture_click".

Я хочу повторно использовать одну и ту же функцию для каждого элемента управления изображением, которую я могу легко назначить с помощью атрибута MouseDown в XAML. Однако я не знаю, как узнать, из какой функции вызвал элемент управления, или как получить доступ к свойству этого элемента управления, например, ".Source". Я хочу иметь возможность захватить имя файла изображения, а также переместить координаты зеленой границы за новым выделением.

Прямо сейчас, я просто жестко запрограммировал первый элемент управления изображением. Щелчки на других изображениях вызовут функцию, но функция выберет только первое изображение (а не то, которое было фактически нажато).

// click on tile 1
private void texture_click (object sender, MouseButtonEventArgs e)
  {
  tile_border.Visibility = Visibility.Visible;

  current_tilefile = tile_image1.Source;
  string source_string = Convert.ToString (tile_image1.Source);
  int last_slash = source_string.LastIndexOf ('/');
  current_tile = source_string.Substring (last_slash + 1, 3);
  }

Я попытался использовать "sender", так как думал, что это может быть объект, вызвавший функцию, но это вернуло ошибку. Я также попытался вызвать функцию с помощью "texture_click (this)", но это также не помогло. По общему признанию, это были полные снимки в темноте, поэтому я не удивился.

Я все еще довольно новичок в этом программном обеспечении, поэтому любые идеи, которые вы, ребята, можете дать, были бы великолепны.

1 ответ

Решение

Вам просто нужно разыграть sender Параметр для типа элемента управления (Изображение в данном случае):

private void texture_click (object sender, MouseButtonEventArgs e)
{
    //tile_border.Visibility = Visibility.Visible;
    var image = sender as Image;
    if (image != null)
    {
        current_tilefile = image.Source;
        string source_string = image.Source.ToString();
        int last_slash = source_string.LastIndexOf ('/');
        current_tile = source_string.Substring (last_slash + 1, 3);
    }
}

Конечно, это не дает вам доступ к соответствующей границе. Одна вещь, которую вы можете сделать, это просто сбросить границу в изображение Tag имущество:

<Image x:Name="tile_image1" ... Tag="{Binding ElementName=tile_border}" />
<Border x:Name="tile_border" ... />

Затем вы можете получить его снова, приведя:

private void texture_click (object sender, MouseButtonEventArgs e)
{
    var image = sender as Image;
    if (image != null)
    {
        var border = image.Tag as Border;
        if (border != null)
        {
            border.Visibility = Visibility.Visible;
        }
        // ...
    }
}

Обратите внимание, что это (манипулирование элементами пользовательского интерфейса из кода) не является идеальным способом написания приложения WPF. Обычно вы делаете что-то подобное, используя существующий элемент управления (например, ToggleButton), и переписать его ControlTemplate так что его IsChecked визуальное состояние показывает границу. Но я понимаю, что это глоток...

Другие вопросы по тегам