Я обнаружил, что WPF combobox.SelectedItem
не обновляется, если я использую DataTemplate для привязки VM к View , но он будет обновляться, если я использую Просмотр напрямую. Вот мой код.
App.xaml
<Application.Resources>
<DataTemplate DataType="{x:Type local:SalesPeriodVM}">
<local:View />
</DataTemplate>
</Application.Resources>
View.xaml
<Grid>
<ComboBox ItemsSource="{Binding SalesPeriods}" SelectionChanged="ComboBox_SelectionChanged"
SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
</Grid>
MainWindow.xaml.cs (код позади)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
int currCount = 0;
private void GotfocusClick(object sender, RoutedEventArgs e)
{
currCount = currCount+1;
salesVM.SelectedItem = salesVM.SalesPeriods[currCount % salesVM.SalesPeriods.Count];
}
}
MainWindow.xaml
<Window x:Class="SyncfusionWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SyncfusionWPF"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:SalesPeriodVM x:Name="salesVM"/>
</Window.DataContext>
<Grid>
<TabControl x:Name="tabCOntrol1" Visibility="Visible">
<TabItem Header="Item2" GotFocus="GotfocusClick">
</TabItem>
<TabItem Header="Item1">
<!--<local:View /> this works-->
<local:SalesPeriodVM /> <!--this doesn't work-->
</TabItem>
</TabControl>
</Grid>
</Window>
Код моей модели просмотра:
public class SalesPeriodVM : INotifyPropertyChanged
{
private ObservableCollection<SalesPeriodV> salesPeriods = new ObservableCollection<SalesPeriodV>();
public ObservableCollection<SalesPeriodV> SalesPeriods
{
get { return salesPeriods; }
set { salesPeriods = value; NotifyPropertyChanged("SalesPeriods"); }
}
private SalesPeriodV selectedItem = new SalesPeriodV();
public SalesPeriodV SelectedItem
{
get { return selectedItem; }
set { selectedItem = value; NotifyPropertyChanged("SelectedItem"); }
}
public SalesPeriodVM()
{
SalesPeriods.Add(new SalesPeriodV() { Month = 1, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 2, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 3, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 4, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 5, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 6, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 7, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 8, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 9, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 10, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 11, Year = 1 });
SalesPeriods.Add(new SalesPeriodV() { Month = 12, Year = 1 });
SelectedItem = SalesPeriods[1];
}
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
PropertyChanged(this, new PropertyChangedEventArgs("HasError"));
}
}
}
public class SalesPeriodV : INotifyPropertyChanged
{
private int month, year;
public int Year
{
get { return year; }
set
{
if (year != value)
{
year = value;
NotifyPropertyChanged("Year");
}
}
}
public int Month
{
get { return month; }
set
{
if (month != value)
{
month = value;
NotifyPropertyChanged("Month");
}
}
}
public override string ToString()
{
return String.Format("{0:D2}.{1}", Month, Year);
}
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(params string[] propertyNames)
{
if (PropertyChanged != null)
{
foreach (string propertyName in propertyNames) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
PropertyChanged(this, new PropertyChangedEventArgs("HasError"));
}
}
}
Итак, если я встраиваю <local:SalesPeriodVM />
в Item1
, то когда Item2
получает фокус, combobox.SelectedItem
в View не обновляется. Имейте в виду, что salesVM.SelectedItem
действительно настроен. Просто пользовательский интерфейс не обновляется.
Что действительно интересно, так это то, что если я закомментирую <local:SalesPeriodVM />
и вместо этого вставлю <local:View />
в Item1
, то когда я нажму на вкладку Item2
, combobox.SelectedItem
в представлении будет обновлено!
Я думал, что оба встраивания <local:SalesPeriodVM />
и <local:View />
должны быть эквивалентны, но почему это не так? Любая идея, как убедиться, что ComboBox.SelectedItem
обновляется, если мне нужно используйте <local:SalesPeriodVM />
?