英文:
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<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);
//LabelCommand = new MyVievModel(o => MainLabelClick("MainButton"));
}
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>
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:
<StackPanel x:Name="ElementHost>
</StackPanel>
<Button Click="OnClick" />
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
<Window>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<ListBox SelectedItem="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Visibility="{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}" />
<Button Command="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.ToggleIsEnabledCommand}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
MainWindow.xaml.cs
partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
MainViewModel.cs
class MainViewModel : INotifyPropertyChanged
{
public ICommand ToggleIsEnabledCommand => new ToggleIsEnabledCommand(ExecuteToggleIsEnabledCommand, commandParameter => 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:
<StackPanel x:Name="ElementHost>
</StackPanel>
<Button Click="OnClick" />
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
<Window>
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
</Window.Resources>
<ListBox SelectedItem="{Binding SelectedItem}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Visibility="{Binding IsEnabled, Converter={StaticResource BooleanToVisibilityConverter}" />
<Button Command="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.ToggleIsEnabledCommand}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
MainWindow.xaml.cs
partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
MainViewModel.cs
class MainViewModel : INotifyPropertyChanged
{
public ICommand ToggleIsEnabledCommand => new ToggleIsEnabledCommand(ExecuteToggleIsEnabledCommand, commandParameter => true);
// TODO::Raise PropertyChanged event
public object SelectedItem { get; set; }
private void ToggleIsEnabledCommand(object commandParameter)
{
(this.SelectedItem as ItemModel).IsEnabled ^= true;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论