Mam trudności z wiązaniem danych na moich niestandardowych kontrolkach użytkownika. Stworzyłem przykładowy projekt, aby podkreślić mój problem. Jestem całkowicie nowy w WPF i zasadniczo również w MVVM, więc proszę o mnie ...Powiązanie w zależności od właściwości niestandardowej Kontrola użytkownika nie jest aktualizowana po zmianie
Stworzyłem prosty widok, który wykorzystuje wiązanie danych na dwa sposoby. Databinding na wbudowanym sterowaniu działa dobrze. Moja kontrola niestandardowa nie ... Postawiłem punkt kontrolny w mojej kontroli. Zostaje trafiony raz podczas uruchamiania, ale nigdy więcej. Tymczasem etykieta, którą związałem z tą samą wartością, radośnie się odlicza.
Czego mi brakuje? Mój przykład projekt następująco:
Okno główne:
<Window x:Class="WpfMVVMApp.MainWindow"
xmlns:local="clr-namespace:WpfMVVMApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.DataContext>
<local:CountdownViewModel />
</Grid.DataContext>
<Label Name="custName" Content="{Binding Path=Countdown.ChargeTimeRemaining_Mins}" Height="45" VerticalAlignment="Top"></Label>
<local:UserControl1 MinutesRemaining="{Binding Path=Countdown.ChargeTimeRemaining_Mins}" Height="45"></local:UserControl1>
</Grid>
</Window>
Oto mój model:
namespace WpfMVVMApp
{
public class CountdownModel : INotifyPropertyChanged
{
private int chargeTimeRemaining_Mins;
public int ChargeTimeRemaining_Mins
{
get
{
return chargeTimeRemaining_Mins;
}
set
{
chargeTimeRemaining_Mins = value;
OnPropertyChanged("ChargeTimeRemaining_Mins");
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
ViewModel:
namespace WpfMVVMApp
{
public class CountdownViewModel
{
public CountdownModel Countdown { get; set; }
DispatcherTimer timer;
private const int maxMins = 360;
public CountdownViewModel()
{
Countdown = new CountdownModel { ChargeTimeRemaining_Mins = 60 };
// Setup timers
timer = new DispatcherTimer();
timer.Tick += new EventHandler(this.SystemChargeTimerService);
timer.Interval = new TimeSpan(0, 0, 1);
timer.Start();
}
private void SystemChargeTimerService(object sender, EventArgs e)
{
//convert to minutes remaining
// DEMO CODE - TODO: Remove
this.Countdown.ChargeTimeRemaining_Mins -= 1;
}
}
}
Oto XAML za moją kontrolą użytkownika:
<UserControl x:Class="WpfMVVMApp.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Label Name="Readout"></Label>
</Grid>
</UserControl>
A oto kod za kontrolą użytkownika:
namespace WpfMVVMApp
{
public partial class UserControl1 : UserControl
{
#region Dependency Properties
public static readonly DependencyProperty MinutesRemainingProperty =
DependencyProperty.Register
(
"MinutesRemaining", typeof(int), typeof(UserControl1),
new UIPropertyMetadata(10, new PropertyChangedCallback(minutesRemainChangedCallBack))
);
#endregion
public int MinutesRemaining
{
get
{
return (int)GetValue(MinutesRemainingProperty);
}
set
{
SetValue(MinutesRemainingProperty, value);
}
}
static void minutesRemainChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args)
{
UserControl1 _readout = (UserControl1)property;
_readout.MinutesRemaining = (int)args.NewValue;
_readout.Readout.Content = _readout.MinutesRemaining;
}
public UserControl1()
{
InitializeComponent();
}
}
}
Dziękuję za odpowiedź. Wiązanie to działało. Jednak powodem, dla którego utworzyłem właściwość zależności, jest to, że chcę zrobić coś więcej niż tylko ustawić etykietę w moim rzeczywistym programie (był to tylko prosty przykład). Teraz widzę, że przypisałem wartość do MinutesRemaining w moim wywołaniu zmiany, która zrywa oryginalne powiązanie. Skomentowałem tę linię i teraz działa tak, jak się spodziewałem. – user2367999