MVVM WPF: изменить свойство элемента по имени из ViewModel - PullRequest
1 голос
/ 27 февраля 2020

Допустим, у меня есть 12 прямоугольников, определенных на странице XAMl, например:

<Rectangle x:Name="C" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="10,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="D" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="78,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="E" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="146,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="F" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="214,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="G" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="281,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="A" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="347,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="B" Fill="#FFF4F4F5" HorizontalAlignment="Left" Height="226" Margin="414,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>
<Rectangle x:Name="CSh" Fill="Black" HorizontalAlignment="Left" Height="121" Margin="47,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="63"/>
<Rectangle x:Name="DSh" Fill="Black" HorizontalAlignment="Left" Height="121" Margin="115,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="62"/>
<Rectangle x:Name="FSh" Fill="Black" HorizontalAlignment="Left" Height="121" Margin="249,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="63"/>
<Rectangle x:Name="GSh" Fill="Black" HorizontalAlignment="Left" Height="121" Margin="317,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="63"/>
<Rectangle x:Name="ASh" Fill="Black" HorizontalAlignment="Left" Height="121" Margin="385,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="63"/>

Как изменить цвет указанного c прямоугольник из ViewModel без использования CodeBehind ?

ПРИМЕР : если я нажму клавишу «A» на моей клавиатуре, элемент на моей странице xaml с именем «A» будет окрашен в зеленый цвет, если я нажму «B» на моем Клавиатура: элемент «B» в моем XAML должен быть окрашен в зеленый цвет и т. д.

У меня уже есть базовое понимание того, как работает связывание, но я не могу найти какое-либо решение, Кто-нибудь может указать мне правильное направление?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2020

Это поведение для Window:

using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Shapes;

public class ListenKeyBehavior : Behavior<Window>
{
    public Brush KeyBgBrush { get; set; }
    private Brush _originalBgBrush;

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
        AssociatedObject.PreviewKeyUp += AssociatedObject_PreviewKeyUp;
    }

    private void AssociatedObject_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var foundEl = GetChildByName(AssociatedObject, e.Key.ToString().ToLower()) as Shape;
        if (foundEl != null && KeyBgBrush != null && _originalBgBrush==null)
        {
            _originalBgBrush = foundEl.Fill;
            foundEl.Fill = KeyBgBrush;
        }
    }

    private void AssociatedObject_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        var foundEl = GetChildByName(AssociatedObject, e.Key.ToString().ToLower()) as Shape;
        if (foundEl != null && _originalBgBrush != null)
        {
            foundEl.Fill = _originalBgBrush;
            _originalBgBrush = null;
        }
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown;
        AssociatedObject.PreviewKeyUp -= AssociatedObject_PreviewKeyUp;
        base.OnDetaching();
    }
    public static object GetChildByName(DependencyObject depObj, string searchedName) 
    {
        if (depObj == null)
        {
            return null;
        }

        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
        {
            var child = VisualTreeHelper.GetChild(depObj, i);
            if (child is FrameworkElement childFrmWrkEl && childFrmWrkEl.Name.ToLower()==searchedName)
            {
                return child;
            }
            var result = GetChildByName(child, searchedName);
            if (result != null)
            {
                return result;
            }
        }
        return null;
    }
}

Примените это поведение к Window:

<Window ..... xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
    <i:Interaction.Behaviors>
        <local:ListenKeyBehavior KeyBgBrush="Green" />
    </i:Interaction.Behaviors>
    .....
</Window>
0 голосов
/ 28 февраля 2020

Сначала вам нужно добавить это к вашему коду xaml

<Rectangle x:Name="C" Fill="{Binding Color}" HorizontalAlignment="Left" Height="226" Margin="10,10,0,0" Stroke="Black" VerticalAlignment="Top" Width="69"/>

Затем вам нужно создать ViewModel

publuc MyViewModel() :INotifyPropertyChanged
{
        Brush _color;
        Brush Color{get{return _color;} set{_color = value; OnPropertyChanged("Color")}}

  public MyViewModel()
  {
      Color = Brushes.Green;
  }
}

и в конце добавить в свой класс xaml.cs вашего window

DataContext = new DERDashboardUserControlViewModel();

Вы можете добавить кнопку вокруг вашего Rectangle и создать команду, которая будет привязана к методу в вашей View Model. Вот ссылка, как это сделать. Как связать кнопку WPF с командой в ViewModel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...