#c# #wpf #xaml #desktop-application
#c# #wpf #xaml #рабочий стол-приложение
Вопрос:
Я пытаюсь создать небольшую программу, тогда как если вы нажмете кнопку увеличения, число добавит 1, и наоборот для кнопки уменьшения.
Мне удалось привязать значение _number к текстовому блоку (изначально заданному как 0), но когда я нажимаю кнопки, ни одна из них, похоже, не добавляет или не вычитает значение. Или если значение изменилось, но не обновилось в окне.
.xaml
// MainWindow.xaml
<Window x:Class="Home_Test.MainWindow"
...
Title="MainWindow" Height="450" Width="800">
<Grid Name="MainGrid">
<Button ...
Content="Add"
Click="increase"/>
<Button ...
Content="Subtract"
Click="decrease"/>
<TextBlock
Name="txtbox"
HorizontalAlignment="Center"
Height="23"
TextWrapping="Wrap"
Text="{Binding Path=Number}"
Width="120"
Margin="0,100,0,0" />
</Grid>
.xaml.cs
using System;
using System.Windows;
using System.ComponentModel;
using System.Runtime.CompilerServices;
...
namespace Home_Test
{
public partial class MainWindow : INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private int _number = 0;
public int Number
{
get { return _number; }
set
{
if (_number != value)
{
_number = value;
}
}
}
public void increase(object sender, RoutedEventArgs e)
{
_number = 1;
}
public void decrease(object sender, RoutedEventArgs e)
{
_number -= 1;
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
В целом, я ожидал, что моя программа добавит 1 или вычтет 1 при нажатии кнопки. Я делаю что-то не так здесь?
Ответ №1:
У вас есть правильная идея, но у вас есть пара недостающих элементов:
1) Пользовательский интерфейс XAML отслеживает Number
свойство на предмет изменений, чтобы оно могло обновляться, но ваши increase()
decrease()
методы and обновляют только резервную переменную. Вы должны установить Number
свойство напрямую.
2) Ваш метод Number
установки должен сообщать пользовательскому интерфейсу XAML об обновлении при его изменении. Это делается путем вызова OnPropertyChangedEvent в установщике свойств — см. https://docs.microsoft.com/en-us/dotnet/framework/winforms/how-to-implement-the-inotifypropertychanged-interface (В нем говорится о Windows forms, но механизм тот же)
Ответ №2:
Ваш XAML выглядит хорошо. Просто чтобы уточнить, вы не привязывались _number
к текстовому блоку. _number
является частной переменной и недоступна для пользовательского интерфейса. Вы привязали общедоступное свойство Number
к текстовому блоку, как и следовало ожидать.
Как описывал Марс в своем посте, проблема возникает в вашей ViewModel. Установщику вашего Number
свойства требуется вызов вашего метода PropertyChanged, который необходимо добавить; а ваши методы увеличения и уменьшения должны изменять Number
свойство напрямую, а не его вспомогательную переменную. Когда вы просто изменяете резервную переменную, установщик вашего свойства никогда не вызывается, и поэтому пользовательский интерфейс никогда не обновляется.
Ниже показаны необходимые изменения кода:
private int _number = 0;
public int Number
{
get { return _number; }
set
{
if (_number != value)
{
_number = value;
//After the setter updates the backing variable, this Updates the UI.
NotifyPropertyChanged("Number");
}
}
}
public void increase(object sender, RoutedEventArgs e)
{
Number = 1;
}
public void decrease(object sender, RoutedEventArgs e)
{
Number -= 1;
}
Добавьте этот код, чтобы NotifyPropetyChanged
функциональность работала.
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Вы были там большую часть пути.
Ответ №3:
Метод set свойства number не запускает событие OnPropertyChanged . Подробности см. здесь https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/how-to-implement-property-change-notification