英文:
Binding attached properties and view models in MVVM | WPF
问题
以下是您要翻译的内容:
"HomeButtonViewModel" 类:
public class HomeButtonViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private double canvasTop;
public double CanvasTop {
get => canvasTop;
set {
canvasTop = value;
OnPropertyChanged(nameof(CanvasTop));
}
}
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
"UserSettingsButtonViewModel" 类与之类似:
public class UserSettingsButtonViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private double canvasTop = 102;
private double canvasLeft = -1;
public double CanvasTop {
get => canvasTop;
set {
canvasTop = value;
OnPropertyChanged(nameof(CanvasTop));
}
}
public double CanvasLeft {
get => canvasLeft;
set {
canvasLeft = value;
OnPropertyChanged(nameof(canvasLeft));
}
}
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
在单击按钮 "Change" 时更改这些属性的代码:
private void changeButton_Click(object sender, RoutedEventArgs e) {
bool mode = !(bool)Settings.Default["mode7"];
Settings.Default["mode7"] = mode;
Settings.Default.Save();
var h = new HomeButtonViewModel() {
CanvasTop = mode ? 1 : 0
};
var us = new UserSettingsButtonViewModel() {
CanvasTop = mode ? 102 : double.NaN,
CanvasLeft = mode ? -1 : double.NaN
};
}
请注意,我已将HTML实体转义字符还原为原始字符,以便更好地呈现代码。如果您需要进一步的帮助或解决其他问题,请告诉我。
英文:
There's my project tree:
MRE_WPF
|
--ViewModels
|
--MainWindowButtons
|
--HomeButtonViewModel.cs
--UserSettingsButtonViewModel.cs
--MainWindow.xaml
--MainWindow.xaml.cs
I have three buttons on main window.
<Window x:Class="MRE_WPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MRE_WPF"
xmlns:main_window_buttons="clr-namespace:MRE_WPF.ViewModels.MainWindowButtons"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Canvas Height="480" Name="MainCanvas">
<Button x:Name="homeButton"
Height="55"
Width="75"
Background="#FF334166"
Foreground="{x:Null}"
FontSize="24"
BorderBrush="{x:Null}"
FontFamily="Tahoma"
Canvas.Top="{Binding Path=(main_window_buttons:HomeButtonViewModel.CanvasTop), Mode=TwoWay, RelativeSource={RelativeSource Self}}"
>
<TextBlock Text="Home" Foreground="White"/>
</Button>
<Button x:Name="userSetingsButton"
Height="55"
Width="75"
Background="#FF334166"
Foreground="{x:Null}"
FontSize="20"
BorderBrush="{x:Null}"
FontFamily="Tahoma"
Canvas.Top="{Binding Path=(main_window_buttons:UserSettingsButtonViewModel.CanvasTop), Mode=TwoWay, RelativeSource={RelativeSource Self}}"
Canvas.Left="{Binding Path=(main_window_buttons:UserSettingsButtonViewModel.CanvasLeft), Mode=TwoWay, RelativeSource={RelativeSource Self}}"
>
<TextBlock Text="User set" Foreground="White"/>
</Button>
<Button x:Name="changeButton"
Height="55"
Width="75"
Background="#FF334166"
Foreground="{x:Null}"
FontSize="20"
Click="changeButton_Click"
BorderBrush="{x:Null}"
FontFamily="Tahoma"
Canvas.Top="100"
Canvas.Left="500">
<TextBlock Text="Change" Foreground="White"></TextBlock>
</Button>
</Canvas>
</Window>
HomeButtonViewModel
class:
public class HomeButtonViewModel:INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private double canvasTop;
public double CanvasTop {
get => canvasTop;
set {
canvasTop = value;
OnPropertyChanged(nameof(CanvasTop));
}
}
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
UserSettingsButtonViewModel
is pretty much the same:
public class UserSettingsButtonViewModel:INotifyPropertyChanged {
public event PropertyChangedEventHandler? PropertyChanged;
private double canvasTop = 102;
private double canvasLeft = -1;
public double CanvasTop {
get => canvasTop;
set {
canvasTop = value;
OnPropertyChanged(nameof(CanvasTop));
}
}
public double CanvasLeft {
get => canvasLeft;
set {
canvasLeft = value;
OnPropertyChanged(nameof(canvasLeft));
}
}
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
I want to change those properties on click on button Change
:
private void changeButton_Click(object sender, RoutedEventArgs e) {
bool mode = !(bool)Settings.Default["mode7"];
Settings.Default["mode7"] = mode;
Settings.Default.Save();
var h = new HomeButtonViewModel() {
CanvasTop = mode ? 1 : 0
};
var us = new UserSettingsButtonViewModel() {
CanvasTop = mode ? 102 : double.NaN,
CanvasLeft = mode ? -1 : double.NaN
};
}
But on click nothing happens. I know that I do something wrong, but I don't know what.
//Also I want use command instead of Click, but let's solve one problem per question.
答案1
得分: 2
以下是您要翻译的内容:
"It's unclear why you have two view models.
Anyway, you should set the DataContext
of the window to an instance of a single view model. In this once you could then initialize the child view models:
public class MainWindowVieModel
{
public HomeButtonViewModel HomeButtonViewModel { get; }
= new HomeButtonViewModel();
public UserSettingsButtonViewModel UserSettingsButtonViewModel { get; }
= new UserSettingsButtonViewModel();
}
You could then bind to the child view models through the main view model/DataContext
in the view using the following syntax:
Finally, you need to set the properties of the view model instance(s) that you actually bind to in the code-behind of the window (where you should also set the DataContext
of the window):
public partial class MainWindow : Window
{
private readonly MainWindowVieModel _viewModel = new MainWindowVieModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
private void changeButton_Click(object sender, RoutedEventArgs e)
{
bool mode = !(bool)Settings.Default["mode7"];
Settings.Default["mode7"] = mode;
Settings.Default.Save();
_viewModel.HomeButtonViewModel.CanvasTop = mode ? 1 : 0;
_viewModel.UserSettingsButtonViewModel.CanvasTop = mode ? 102 : double.NaN;
_viewModel.UserSettingsButtonViewModel.CanvasLeft = mode ? -1 : double.NaN;
}
}"
请注意,代码中的 HTML 编码已被还原为原始文本。
英文:
It's unclear why you have two view models.
Anyway, you should set the DataContext
of the window to an instance of a single view model. In this once you could then initialize the child view models:
public class MainWindowVieModel
{
public HomeButtonViewModel HomeButtonViewModel { get; }
= new HomeButtonViewModel();
public UserSettingsButtonViewModel UserSettingsButtonViewModel { get; }
= new UserSettingsButtonViewModel();
}
You could then bind to the child view models through the main view model/DataContext
in the view using the following syntax:
<Button x:Name="homeButton"
Height="55"
Width="75"
Background="#FF334166"
Foreground="{x:Null}"
FontSize="24"
BorderBrush="{x:Null}"
FontFamily="Tahoma"
Canvas.Top="{Binding HomeButtonViewModel.CanvasTop}"
>
<TextBlock Text="Home" Foreground="White"/>
</Button>
<Button x:Name="userSetingsButton"
Height="55"
Width="75"
Background="#FF334166"
Foreground="{x:Null}"
FontSize="20"
BorderBrush="{x:Null}"
FontFamily="Tahoma"
Canvas.Top="{Binding UserSettingsButtonViewModel.CanvasTop}"
Canvas.Left="{Binding UserSettingsButtonViewModel.CanvasLeft}"
>
<TextBlock Text="User set" Foreground="White"/>
</Button>
Finally, you need to set the properties of the view model instance(s) that you actually bind to in the code-behind of the window (where you should also set the DataContext
of the window):
public partial class MainWindow : Window
{
private readonly MainWindowVieModel _viewModel = new MainWindowVieModel();
public MainWindow()
{
InitializeComponent();
DataContext = _viewModel;
}
private void changeButton_Click(object sender, RoutedEventArgs e)
{
bool mode = !(bool)Settings.Default["mode7"];
Settings.Default["mode7"] = mode;
Settings.Default.Save();
_viewModel.HomeButtonViewModel.CanvasTop = mode ? 1 : 0;
_viewModel.UserSettingsButtonViewModel.CanvasTop = mode ? 102 : double.NaN;
_viewModel.UserSettingsButtonViewModel.CanvasLeft = mode ? -1 : double.NaN;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论