2015-12-17 15 views
5

Tôi là người mới bắt đầu thực sự trong mẫu MVVM. Tôi đang cố gắng thay đổi backgound của một lưới trên nhấp chuột của nút. Tôi có một xaml với một lưới có chứa một nút, và một ViewModel .cs từ nơi tôi muốn thay đổi nền của lưới trên nhấp chuột của nút. Cho đến khi có tôi chỉ thành công xuất hiện một MessageBox khi tôi nhấp ...Thay đổi màu nền của lưới MVVM khi nhấp vào

đang .xaml:

<Window x:Class="WpfSimple.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfSimple" 
    Title="MainWindow" Height="150" Width="370"> 
<Window.DataContext> 
    <local:MainWindowViewModel/> 
</Window.DataContext> 
    <Grid> 
    <Button Content="Click" 
      Height="23" 
      HorizontalAlignment="Left" 
      Background="Gray" 
      Margin="75.944,47.465,0,0" 
      Name="btnClick" 
      VerticalAlignment="Top" 
      Width="203" 
      Command="{Binding ButtonCommand}"/> 
     <!--What is necessary to add for changing grid color ? Commandparameter ?--> 
</Grid> 

MainWindowViewModel.cs mã:

namespace WpfSimple 
{ 
    class MainWindowViewModel 
    { 
     private ICommand m_ButtonCommand; 
     public ICommand ButtonCommand 
     { 
      get 
      { 
       return m_ButtonCommand; 
      } 
      set 
      { 
       m_ButtonCommand = value; 
      } 
     } 

     public MainWindowViewModel() 
     { 
      ButtonCommand=new RelayCommand(new Action<object>(ChangeBgColor)); 
     } 

     public void ChangeBgColor(object obj) 
     { 
      /*HERE I WANT TO CHANGE GRID COLOR*/ 
     } 
    } 
} 

Xin lỗi vì tôi tiếng Anh kém.

Trân trọng.

Trả lời

1

Fitst của tất cả các bạn nên thực hiện INotifyPropertyChanged trong ViewModel của bạn:

public class MainWindowViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    // This method is called by the Set accessor of each property. 
    // The CallerMemberName attribute that is applied to the optional propertyName 
    // parameter causes the property name of the caller to be substituted as an argument. 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 

Sau đó, thêm NotifyPropertyChanged() để tính setter của bạn.

Ok. Tiếp theo, thêm tài sản mới với màu nền lưới của bạn để ViewModel của bạn:

private Brush _gridBackground; 
public Brush GridBackground 
{ 
    get { return _gridBackground; } 
    set 
    { 
     _gridBackground = value; 
     NotifyPropertyChanged(); 
    } 
} 

Và kết nền của lưới của bạn đến tài sản của bạn:

<Grid Background="{Binding GridBackground}"> 

Cuối cùng bạn chỉ có thể thay đổi GridBackground trong xử lý lệnh:

public void ChangeBgColor(object obj) 
{ 
    GridBackground = Brushes.Blue; 
} 

Bạn nên nhớ rằng thực tiễn không tốt là thêm các lớp WPF như Brush vào mã của bạn. Cách tốt hơn là sử dụng IValueConverter trong mã XAML và các lớp BCL trong ViewModel của bạn. Ví dụ, bạn có thể sử dụng liệt kê trong ViewModel và chuyển nó thành brush trong ValueConverter.

  1. Thêm enum mới cho bất động sản ViewModel của bạn:

    public enum GridState { Valid, Invalid } 
    
  2. Thay đổi loại tài sản:

    private GridState _gridBackground; 
    public GridState GridBackground 
    { 
        get { return _gridBackground; } 
        set 
        { 
         _gridBackground = value; 
         NotifyPropertyChanged(); 
        } 
    } 
    
  3. Thêm lớp mới với chuyển đổi giá trị

    public class GridStateToBackgroundColorConverter : IValueConverter 
    { 
        #region IValueConverter Members 
    
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        { 
         GridState val = (GridState) value; 
         if(val == GridState.Valid) 
          return Brushes.Green; 
         return Brushes.Red; 
        } 
    
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
        { 
         throw new NotSupportedException(); 
        } 
    
        #endregion 
    } 
    
  4. Thêm tài nguyên tĩnh mới để kiểm soát của bạn

    <UserControl.Resources> 
        <converters:GridStateToBackgroundColorConverter x:Key="gridStateToBackgroundColorConverter" /> 
    </UserControl.Resources> 
    
  5. Cập nhật liên kết đến tài sản

    <Grid Background="{Binding GridBackground, Converter={StaticResource gridStateToBackgroundColorConverter}"> 
    
+0

CÓ! Cảm ơn rất nhiều Vadim Martynov! Tôi không chắc chắn rằng tôi hiểu mục đích của "Giao diện INotifyPropertyChanged" bởi vì nó được thông báo cho tôi không có gì cả ... nhưng câu trả lời của bạn thực sự hữu ích. Trân trọng. – Chefty

+0

@Chất lượng INPC được yêu cầu cho dữ liệu bindng. Nếu không có nó, màu của bạn sẽ không thay đổi khi bạn thay đổi thuộc tính trong ViewModel. Ngoài ra, INPC là một tính năng thông thường của ràng buộc dữ liệu. Bạn có thể đọc thêm về MSDN: https://msdn.microsoft.com/en-US/library/ms752347(v=vs.100).aspx –

+0

Tôi không thể thêm tài nguyên tĩnh mới vào kiểm soát của mình, nó tạo ra lỗi: " GridStateToBackgroundColorConverter không được hỗ trợ trong một dự án WPF "có bình thường không? – Chefty

-1

của bạn Nếu bạn muốn thay đổi màu nền lưới sau đó bạn có thể sử dụng tham số lệnh. Bạn có thể vượt qua bất kỳ điều khiển giao diện người dùng nào dưới dạng tham số Lệnh. Trong trường hợp của bạn, hãy vượt qua lưới để truy cập lưới trong mô hình chế độ xem của bạn. Đặt tên cho lưới của bạn và sử dụng tên đó để sử dụng làm tham số lệnh. Đối với điều này, bạn cần triển khai mã như sau:

<Window x:Class="WpfSimple.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfSimple" 
     Title="MainWindow" Height="150" Width="370"> 
<Window.DataContext> 
    <local:MainWindowViewModel/> 
</Window.DataContext> 
<Grid Name="grid"> 
<Button Content="Click" 
     Height="23" 
     HorizontalAlignment="Left" 
     Background="Gray" 
     Margin="75.944,47.465,0,0" 
     Name="btnClick" 
     VerticalAlignment="Top" 
     Width="203" 
     Command="{Binding ButtonCommand}" 
     CommandParameter="{Binding Elementname="grid"}"/> 
</Grid> 

Sau khi thực hiện thay đổi này thành tệp .xaml. Thực hiện lệnh Parameterized Relay để sử dụng Grid được truyền này để sử dụng trong tệp Viewmodel của bạn. Để thực hiện Lệnh chuyển tiếp tham số Cố gắng triển khai mã sau:

private ICommand m_ButtonCommand; 
    public ICommand ButtonCommand 
    { 
     get 
     { 
      return m_ButtonCommand; 
     } 
     set 
     { 
      m_ButtonCommand = value; 
     } 
    } 

    public MainWindowViewModel() 
    { 
     ButtonCommand=new RelayCommand<Grid>(ChangeBgColor); 
    } 

    public void ChangeBgColor(Grid grid) 
    { 
     if(grid!=null) 
      grid.Background = Brushes.Red; //Any color you want to change. 
    } 

Tôi hy vọng điều này sẽ hiệu quả. Cảm ơn bạn.

+0

Xin chào! Cảm ơn bạn Dhruv Panchal, nhưng nó không hoạt động. "RelayCommand " tạo ra lỗi và tôi không thể giải quyết lỗi đó. – Chefty

+0

@Chefty Lỗi nào bạn đang gặp phải? Bạn có thể cho tôi biết không? Bạn đã triển khai RelayCommand trong đơn đăng ký của mình chưa? –

+0

Nó nói với tôi rằng RelayCommand không thể được sử dụng với các đối số kiểu. – Chefty

Các vấn đề liên quan