目前我的Viewmodel中有一个MyClass的ObservableCollection。我使用此Collection的getter从其他Datasource填充它。我现在可以在窗口(网格)中显示此数据并显示正确的数据,但是当我更改数据时,不会触发该集合(我认为这是因为集合没有被更改,只有集合中的元素)。我应该为MyClass的每个属性创建一个属性,所以我可以对单个值的更改做出反应,我问自己的问题是:
当我的Collection更改时,我也想到了一个事件,但我不确定如何正确实现它。
public ObservableCollection<MyClass<string>> SelectedParams
{
get
{
//Fill the Collection
}
set
{
//I think here i want to react to changed Textboxvalues in my View
}
}
public class MyClass<T> : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private T _curValue;
private string _value1;
private string _value2;
public string Value1
{
get
{
return _value1;
}
set
{
if (_value1 != value)
{
_value1 = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value1)));
}
}
}
public string Value2
{
get
{
return _value2;
}
set
{
if (_value2 != value)
{
_value2 = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Value2)));
}
}
}
public T curValue
{
get
{
return _curValue;
}
set
{
_curValue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(curValue)));
}
}
public MyClass()
{
}
public MyClass(string val1, string val2, T curVal)
{
Value1 = val1;
Value2 = val2;
curValue = curVal;
}
}
xaml代码看起来像这样
<ItemsControl ItemsSource="{Binding SelectedParams}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="{Binding Value1}"/>
<Label Grid.Column="1" Content="{Binding Value2}"/>
<TextBox Grid.Column="2" Text="{Binding curValue, Mode=TwoWay}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Edit1:将MyClass更改为INotifyPropertyChanged现在Collection更改了内部值但是在更改值时仍未调用Setter
答案 0 :(得分:0)
您需要为MyClass实现INotifyPropertChanged接口,并在setter中引发PropertyChanged以通知UI属性值已更改。
答案 1 :(得分:0)
我如何知道目前选择的元素
如果您想要支持项目选择,则必须使用其他控件。 ItemsControl不支持选择。
以ListView为例。将ItemsSource和SelectedItem绑定到您的类。现在,每次单击某个项目时,SelectedValue都会更新。如果从代码更改SelectedValue,UI将更新列表中的选定项。您也可以将其他控件绑定到SelectedValue,就像我使用ListView外部的TextBlock一样。
查看强>
<StackPanel>
<ListView ItemsSource="{Binding Values}" SelectedItem="{Binding SelectedValue}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Item1}" />
<TextBlock Text="=" />
<TextBlock Text="{Binding Path=Item2}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackPanel Orientation="Horizontal">
<TextBox Text="Selected:" Background="DarkGray" />
<TextBox Text="{Binding SelectedValue.Item1, Mode=OneWay}" Background="DarkGray" />
</StackPanel>
</StackPanel>
数据强>
public class ListViewBindingViewModel : INotifyPropertyChanged
{
private Tuple<string,int> _selectedValue;
public ObservableCollection<Tuple<string,int>> Values { get; }
public Tuple<string, int> SelectedValue
{
get { return _selectedValue; }
set
{
_selectedValue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedValue)));
}
}
public ListViewBindingViewModel()
{
Values = new ObservableCollection<Tuple<string, int>> {Tuple.Create("Dog", 3), Tuple.Create("Cat", 5), Tuple.Create("Rat",1)};
}
}