Вот мое дерево проекта:
MRE_WPF
|
--ViewModels
|
--MainWindowButtons
|
--HomeButtonViewModel.cs
--UserSettingsButtonViewModel.cs
--MainWindow.xaml
--MainWindow.xaml.cs
У меня есть три кнопки в главном окне.
<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 класс:
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
};
}
Но при клике ничего не происходит. Я знаю, что делаю что-то не так, но не знаю, что.
// Также я хочу использовать команду вместо Click, но давайте решим одну задачу на вопрос.
Да, это было. Было даже в OnPropertyChanged (в обоих случаях), но кнопки не двигались.
Вы ничего не делаете с двумя новыми экземплярами модели представления.
@Энди и я что должны сделать? Хм, может быть, мне нужно создать два свойства в MainWindow.xaml.cs и привязать к ним?
Обычно для каждого представления используется одна модель представления. Если вы хотите что-то изменить, установите для этого свойства. Привязать представление к свойствам модели представления. Inotifypropertychanged указывает представлению перечитать значение.





Непонятно, почему у вас две модели просмотра.
В любом случае, вы должны установить DataContext окна на экземпляр одной модели представления. В этот раз вы можете инициализировать модели дочернего представления:
public class MainWindowVieModel
{
public HomeButtonViewModel HomeButtonViewModel { get; }
= new HomeButtonViewModel();
public UserSettingsButtonViewModel UserSettingsButtonViewModel { get; }
= new UserSettingsButtonViewModel();
}
Затем вы можете привязаться к дочерним моделям представления через модель основного представления/DataContext в представлении, используя следующий синтаксис:
<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>
Наконец, вам нужно установить свойства экземпляра (ов) модели представления, к которым вы фактически привязываетесь, в коде программной части окна (где вы также должны установить DataContext окна):
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;
}
}
Вы пытались использовать точку останова? Он попал в
changeButton_Click?