更改元素的可见性 MVVM wpf

huangapple go评论49阅读模式
英文:

Change visibility of an element MVVM wpf

问题

以下是您要翻译的代码部分:

ViewModelBase

public abstract class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler? PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 
    #endregion
}

MyCommand

public abstract class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler? PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 
    #endregion
}

Model

class MyModel
{
    
    public Visibility myVisibility;
 
}

ViewModel1

public class MMViewModel: ViewModelBase
{
    public System.Windows.Visibility MyVisibility
    {
        get { return M.myVisibility; }
        set
        {
            M.myVisibility = value;
            OnPropertyChanged(nameof(MyVisibility));
        }
    }
}

ViewModel2

private ICommand myCommand;
public ObservableCollection<MMViewModel> mm1;

public ObservableCollection<MMViewModel> MM1
{
    get { return mm1; }
    set
    {
        mm1 = value;
        OnPropertyChanged(nameof(MM1));
    }
}

public ICommand MyButtonClickCommand
{ 
    get { return myCommand; }
    set { myCommand = value; }
}

public MyVievModel()
{
    MM1 = new ObservableCollection<MMViewModel>();
    MM1.Add(new MMViewModel
    {
        MyVisibility = Visibility.Visible
    });
    myCommand = new MyCommand(ChangeVis, ToEvaluate);
}

private void ChangeVis(object context)
{
    MM1[0].MyVisibility = Visibility.Hidden;
}

private bool ToEvaluate(object context)
{
    return true;
}

XAML

<StackPanel>
    <ItemsControl ItemsSource="{Binding Path=MM1}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Background="Black">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition/>
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Border BorderBrush="Blue" BorderThickness="2" Grid.ColumnSpan="2"/>
                    <StackPanel>
                        <Button Grid.Column="0" VerticalAlignment="Center" Content="What is Netflix?"
                            FontSize="30" Foreground="White" Command="{Binding MyButtonClickCommand}">
                        </Button>
                        <TextBlock Grid.Column="1" HorizontalAlignment="Right" Text="+"
                            FontSize="60" Foreground="White">
                        </TextBlock>
                        <StackPanel Margin="0 5 0 0" Visibility="{Binding ChangeVis, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                            <TextBlock Foreground="White" FontSize="20">Text1<LineBreak/>Text1 continue</TextBlock>
                            <TextBlock Margin="0 20 0 0" Foreground="White" FontSize="20">
                                Text2
                            </TextBlock>
                        </StackPanel>
                    </StackPanel>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</StackPanel>
英文:

Just yesterday i've started explored mvvm wpf so please, if I do something wrong, don't beat me! I want to change visibility of stackpanel by click on a button. And I have a problem here. My code:

ViewModelBase

    public abstract class ViewModelBase : INotifyPropertyChanged
        {
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler? PropertyChanged;
            public void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                     PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
 
            #endregion
        }

MyCommand

public abstract class ViewModelBase : INotifyPropertyChanged
{
    #region INotifyPropertyChanged Members
    public event PropertyChangedEventHandler? PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
             PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
 
    #endregion
}

Model

class MyModel
{
    
    public Visibility myVisibility;
 
}

ViewModel1

public class MMViewModel: ViewModelBase
{
    public System.Windows.Visibility MyVisibility
    {
        get { return M.myVisibility; }
        set
        {
            M.myVisibility = value;
            OnPropertyChanged(nameof(MyVisibility));
        }
    }
}

ViewModel2

private ICommand myCommand;
        public ObservableCollection&lt;MMViewModel&gt; mm1;
        
        public ObservableCollection&lt;MMViewModel&gt; MM1
        {
            get { return mm1; }
            set
            {
                mm1 = value;
                OnPropertyChanged(nameof(MM1));
            }
        }
 
        public ICommand MyButtonClickCommand
        { get { return myCommand; }
            set { myCommand = value; }
        }
        public MyVievModel()
        {
            MM1 = new ObservableCollection&lt;MMViewModel&gt;();
            MM1.Add(new MMViewModel
            {
                MyVisibility = Visibility.Visible
            });
            myCommand = new MyCommand(ChangeVis, ToEvaluate);
 
            //LabelCommand = new MyVievModel(o =&gt; MainLabelClick(&quot;MainButton&quot;));
        }
        private void ChangeVis(object context)
        {
 
            MM1[0].MyVisibility = Visibility.Hidden;
        }
        private bool ToEvaluate(object context)
        {
            return true;
        }

XAML

                &lt;StackPanel&gt;
                    &lt;ItemsControl ItemsSource=&quot;{Binding Path=MM1}&quot;&gt;
                        &lt;ItemsControl.ItemTemplate&gt;
                            &lt;DataTemplate&gt;
                                &lt;Grid Background=&quot;Black&quot;&gt;
                                    &lt;Grid.ColumnDefinitions&gt;
                                        &lt;ColumnDefinition/&gt;
                                        &lt;ColumnDefinition/&gt;
                                    &lt;/Grid.ColumnDefinitions&gt;
                                    &lt;Border BorderBrush=&quot;Blue&quot; BorderThickness=&quot;2&quot;
                                      Grid.ColumnSpan=&quot;2&quot;/&gt;
                                    &lt;StackPanel&gt;
                                        &lt;Button Grid.Column=&quot;0&quot; VerticalAlignment=&quot;Center&quot;   
                         Content=&quot;What is Netflix?&quot;
                                           FontSize=&quot;30&quot; Foreground=&quot;White&quot; Command=&quot;{Binding 
                        MyButtonClickCommand}&quot;&gt;
 
                                        &lt;/Button&gt;
                                        &lt;TextBlock Grid.Column=&quot;1&quot; HorizontalAlignment=&quot;Right&quot; 
                                        Text=&quot;+&quot;
                                           FontSize=&quot;60&quot; Foreground=&quot;White&quot;&gt;
                                        &lt;/TextBlock&gt;
                                        &lt;StackPanel Margin=&quot;0 5 0 0&quot; Visibility=&quot;{Binding ChangeVis, 
                                Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}&quot;&gt;
                                            &lt;TextBlock Foreground=&quot;White&quot; 
                             FontSize=&quot;20&quot;&gt;Text1&lt;LineBreak/&gt; Text1 continue&lt;/TextBlock&gt;
                                            &lt;TextBlock Margin=&quot;0 20 0 0&quot; Foreground=&quot;White&quot; 
                                    FontSize=&quot;20&quot;&gt;
                                        Text2
                                            &lt;/TextBlock&gt;
                                        &lt;/StackPanel&gt;
                                    &lt;/StackPanel&gt;
                                    
                                &lt;/Grid&gt;
 
                            &lt;/DataTemplate&gt;
                        &lt;/ItemsControl.ItemTemplate&gt;
                    &lt;/ItemsControl&gt;
                &lt;/StackPanel&gt;

If you have some tips about how to improve my code - it would be very good! Thanks for your tips and comments!

答案1

得分: 1

The simplest MVVM solution would be to name the StackPanel and change its visibility from code-behind:

&lt;StackPanel x:Name=&quot;ElementHost&gt;

&lt;/StackPanel&gt;
&lt;Button Click=&quot;OnClick&quot; /&gt;
private void OnClick(object sender, RoutedEventArgs e)
{
  this.ElementHost.Visibility = Visibility.Hidden;
}

If you need the value in your view model class, you can bind the Visibility property to a bool property and use the BooleanToVisibilityConverter class:

MainWindow.xaml

&lt;Window&gt;
  &lt;Window.Resources&gt;
    &lt;BooleanToVisibilityConverter x:Key=&quot;BooleanToVisibilityConverter&quot; /&gt;
  &lt;/Window.Resources&gt;

  &lt;ListBox SelectedItem=&quot;{Binding SelectedItem}&quot;&gt;
    &lt;ListBox.ItemTemplate&gt;
      &lt;DataTemplate&gt;
        &lt;StackPanel Visibility=&quot;{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}&quot; /&gt;
        &lt;Button Command=&quot;{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.ToggleIsEnabledCommand}&quot; /&gt;
        &lt;/StackPanel&gt;
      &lt;/DataTemplate&gt;
    &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
&lt;/Window&gt;

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
    this.DataContext = new MainViewModel();
  }
}

MainViewModel.cs

class MainViewModel : INotifyPropertyChanged
{
  public ICommand ToggleIsEnabledCommand =&gt; new ToggleIsEnabledCommand(ExecuteToggleIsEnabledCommand, commandParameter =&gt; true);

  // TODO::Raise PropertyChanged event
  public object SelectedItem { get; set; }

  private void ToggleIsEnabledCommand(object commandParameter)
  {
    (this.SelectedItem as ItemModel).IsEnabled ^= true;
  }
}
英文:

The simplest MVVM solution would be to name the StackPanel and change its visibility from code-behind:

&lt;StackPanel x:Name=&quot;ElementHost&gt;

&lt;/StackPanel&gt;
&lt;Button Click=&quot;OnClick&quot; /&gt;
private void OnClick(object sender, RoutedEventArgs e)
{
  this.ElementHost.Visibility = Visibility.Hidden;
}

If you need the value in your view model class you can bind the Visibilty property to a bool property and use the BooleanToVisibilityConverter class:

MainWindow.xaml

&lt;Window&gt;
  &lt;Window.Resources&gt;
    &lt;BooleanToVisibilityConverter x:Key=&quot;BooleanToVisibilityConverter&quot; /&gt;
  &lt;/Window.Resources&gt;

  &lt;ListBox SelectedItem=&quot;{Binding SelectedItem}&quot;&gt;
    &lt;ListBox.ItemTemplate&gt;
      &lt;DataTemplate&gt;
        &lt;StackPanel Visibility=&quot;{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}&quot; /&gt;
        &lt;Button Command=&quot;{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.ToggleIsEnabledCommand}&quot; /&gt;
        &lt;/StackPanel&gt;
      &lt;/DataTemplate&gt;
    &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
&lt;/Window&gt;

MainWindow.xaml.cs

partial class MainWindow : Window
{
  public MainWindow()
  {
    InitializeComponent();
    this.DataContext = new MainViewModel();
  }
}

MainViewModel.cs

class MainViewModel : INotifyPropertyChanged
{
  public ICommand ToggleIsEnabledCommand =&gt; new ToggleIsEnabledCommand(ExecuteToggleIsEnabledCommand, commandParameter =&gt; true);

  // TODO::Raise PropertyChanged event
  public object SelectedItem { get; set; }

  private void ToggleIsEnabledCommand(object commandParameter)
  {
    (this.SelectedItem as ItemModel).IsEnabled ^= true;
  }
}

huangapple
  • 本文由 发表于 2023年6月13日 01:05:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458855.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定