非MVVM。
我得到了这个由machines
- 类型对象组成的ObservableCollection Machine
:
[Serializable]
[NotifyPropertyChanged]
public abstract class Machine
{
public MachineNames MachineType { get; set; }
public int MachineVersion { get; set; }
public string LatestEditorName { get; set; }
public DateTime LatestSaveTime { get; set; }
public ObservableCollection<Parameter> Parameters { get; set; }
public string Notes { get; set; }
public abstract double CalculateThroughPut();
public Machine()
{
string[] nameParts = this.GetType().Name.Split('_');
Enum.TryParse(nameParts[0], out MachineNames currentMachineType);
MachineType = currentMachineType;
MachineVersion = int.Parse(nameParts[1]);
Parameters = new ObservableCollection<Parameter>();
ICollectionView icv = CollectionViewSource.GetDefaultView(Parameters);
icv.GroupDescriptions.Add(new PropertyGroupDescription("Group"));
LatestEditorName = Environment.UserName;
LatestSaveTime = DateTime.Now;
}
public double getValue(string parameterName)
{
Parameter currentParameter = Parameters.Where(x => x.Name == parameterName).First();
return currentParameter.Value * currentParameter.MetricConversionFactor;
}
以下是宣言:
public partial class MainWindow : MetroWindow
{
IEnumerable<string> namesOfExistingMachines { get; set; }
public ObservableCollection<Machine> machines { get; set; }
以及后来:
private void InitializeData()
{
machines = new ObservableCollection<Machine>();
this.DataContext = machines;
tcMainTabControl.ItemsSource = machines;
请注意,[NotifyPropertyChanged]
标签是PostSharp的一部分,只是让Machine的所有属性都可以更改为绑定。另外,它使属性的所有属性都变得可以改变。
这是XAML的初始窗口部分:
<Grid>
<Controls:MetroAnimatedTabControl Name="tcMainTabControl">
<TabControl.ItemContainerStyle>
<Style TargetType="TabItem">
<Setter Property="ToolTipService.ShowDuration" Value="100000"/>
<Setter Property="ToolTipService.InitialShowDelay" Value="0"/>
<Setter Property="Header" Value="{Binding Converter={StaticResource tabHeaderConverter}}"/>
<Setter Property="ToolTip">
<Setter.Value>
<StackPanel Orientation="Vertical">
<TextBlock HorizontalAlignment="Center" Margin="0,10" FontSize="40" FontWeight="Bold" Text="{Binding Path=MachineType}"/>
<Image HorizontalAlignment="Center" Source="{Binding Path=MachineType, Converter={StaticResource imageUriConverter}}"/>
<StackPanel HorizontalAlignment="Center" Margin="0,10" Orientation="Horizontal">
<TextBlock FontSize="20" Text="Throughput model version "/>
<TextBlock FontSize="20" Text="{Binding Path=MachineVersion}"/>
</StackPanel>
<StackPanel HorizontalAlignment="Center" Margin="0,10" Orientation="Horizontal">
<TextBlock FontSize="20" Text="created by "/>
<TextBlock FontSize="20" Text="{Binding Path=LatestEditorName}"/>
<TextBlock FontSize="20" Text=" on "/>
<TextBlock FontSize="20" Text="{Binding Path=LatestSaveTime, StringFormat=dd/MM/yyyy}"/>
</StackPanel>
<TextBlock Margin="0,10" FontSize="20" Text="{Binding Path=Notes}"/>
</StackPanel>
</Setter.Value>
</Setter>
</Style>
</TabControl.ItemContainerStyle>
<Controls:MetroAnimatedTabControl.ContentTemplate>
<DataTemplate>
<DockPanel LastChildFill="True" Margin="10,0">
<StackPanel Orientation="Vertical">
<Border BorderBrush="{DynamicResource AccentColorBrush}" BorderThickness="1,1,1,1" CornerRadius="8,8,8,8" Margin="0,20" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock FontSize="20" Text="Throughput: "/>
<TextBlock FontSize="20" Text="{Binding Converter={StaticResource throughputCalculationConverter}, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock FontSize="20" Text=" panel sides per hour"/>
</StackPanel>
</Border>
<ListView DockPanel.Dock="Left" ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding Path=Parameters, UpdateSourceTrigger=PropertyChanged}">
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.ContainerStyle>
<Style TargetType="{x:Type GroupItem}">
<Setter Property="Margin" Value="0,0,0,5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<Expander IsExpanded="True" BorderBrush="Black" BorderThickness="0,0,0,1">
<Expander.Header>
<TextBlock FontSize="20" FontWeight="Bold">
<Run>Discipline: </Run>
<TextBlock Text="{Binding Path=Name, Converter={StaticResource titleCaseConverter}}"/>
</TextBlock>
</Expander.Header>
<Expander.Content>
<Border Margin="2" CornerRadius="3">
<ItemsPresenter />
</Border>
</Expander.Content>
</Expander>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.ContainerStyle>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<TextBlock FontSize="20" Text="{Binding Name}" Margin="0,0,10,0" VerticalAlignment="Center"/>
<TextBox FontSize="20" BorderBrush="Black" BorderThickness="0,0,0,1" Background="Transparent" Controls:TextBoxHelper.Watermark="Enter value" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="0,0,10,0" VerticalAlignment="Center" HorizontalContentAlignment="Center"/>
<TextBlock FontSize="20" Text="{Binding Unit}" VerticalAlignment="Center"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="ToolTip" Value="{Binding Path=Notes}"/>
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</StackPanel>
绑定部门的一切都很好。我想要的是每当CollectionChanged
成员中的某个属性在内部更改属性时,为machines
调用Machine
事件(或类似事件)。换句话说:如果我更改Parameter
Parameters
Machine
machine
内的<TextBlock FontSize="20" Text="{Binding Converter={StaticResource throughputCalculationConverter}, UpdateSourceTrigger=PropertyChanged}"/>
,我希望更新计算
Step 3: Startup: Configuration Script
A configuration script will run if this is the first login. When prompted
for HANA database master password, enter a strong password.
Tip: Make a note of this password, since you’ll need it later. You can enter
the same password you used earlier, or a new password. If you are entering a
new password, see the password rules earlier in this tutorial.
XSA_ADMIN
XSA_DEV
XSA_SHINE
TEL_ADMIN
When prompted to Confirm “HANA database master password”, enter the strong
password again.
谢谢!
答案 0 :(得分:1)
要从集合中的项目传播PropertyChanged
通知,您需要订阅其订阅项目更改通知的集合类。标准ObservableCollection<T>
类不会这样做。您可以扩展ObservableCollection<T>
,如下所示。您还可以在SO上找到更多类似的示例(例如ObservableCollection that also monitors changes on the elements in collection)。
[NotifyPropertyChanged]
public class ObservableCollectionEx<T> : ObservableCollection<T>
{
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (T item in e.OldItems)
{
((INotifyPropertyChanged) item).PropertyChanged -= OnItemPropertyChanged;
}
}
else if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (T item in e.NewItems)
{
((INotifyPropertyChanged) item).PropertyChanged += OnItemPropertyChanged;
}
}
base.OnCollectionChanged(e);
}
protected void OnPropertyChanged(string propertyName)
{
base.OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
protected void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
NotifyPropertyChangedServices.SignalPropertyChanged(this, "Item[]");
NotifyCollectionChangedEventArgs collectionChangedEventArgs = new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset);
base.OnCollectionChanged(collectionChangedEventArgs);
}
}
使用此自定义集合类时,集合将在项目的属性更改时引发事件。现在,您还可以使用应用于集合属性的[AggregateAllChanges]
属性(例如Parameters
,machines
)告诉PostSharp将此通知传播为集合属性本身的更改。
[AggregateAllChanges]
public ObservableCollectionEx<Parameter> Parameters { get; set; }
[AggregateAllChanges]
public ObservableCollectionEx<Machine> machines { get; set; }