[英]Binding not updated with DataTemplateSelector
I have a WPF application based on MVVM. 我有一个基于MVVM的WPF应用程序。 It has paramaters that can be set.
它具有可以设置的参数。 A paramater can be a list of strings in a checkbox or a double in a numupdown.
参数可以是复选框中的字符串列表,也可以是numupdown中的双精度字符串。 Every device has its own parameters, so the parameters are dynamically loaded.
每个设备都有自己的参数,因此参数是动态加载的。 Thats why i use a DataTemplateSelector.
那就是为什么我使用DataTemplateSelector。
Xaml code XAML代码
<ItemsControl ItemsSource="{Binding ParameterWrapperList}" ItemTemplateSelector="{StaticResource propertyDataTemplateSelector}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
The templates are in a resource dictionary: 模板在资源字典中:
<DataTemplate x:Key="doubleTemplate"> <Grid Visibility="{Binding Parameter.ParameterModel.IsVisible, Converter={StaticResource Visibility}}"> <Grid.RowDefinitions> <RowDefinition Height="{Binding Path=RowHeight, Mode=OneWay}"/> <RowDefinition/> </Grid.RowDefinitions> <Border Grid.Row="0" Style="{StaticResource HeaderBorderStyle}" Width="{Binding Width}" Visibility="{Binding HeaderVisibility, Converter={StaticResource Visibility}}"> <StackPanel Orientation="Horizontal"> <Label Content="{Binding Parameter.DisplayName}"/> </StackPanel> </Border> <Border Grid.Row="1" Style="{StaticResource ItemBorderStyle}" Width="{Binding Width}"> <telerik:RadNumericUpDown Name="nudParameterValue" Value="{Binding Path=ParameterValue, Mode=TwoWay}" Minimum="{Binding Parameter.ParameterModel.MinimumValue}" Maximum="{Binding Parameter.ParameterModel.MaximumValue}" NumberDecimalDigits="{Binding Parameter.ParameterModel.NumberDecimalDigits}" SmallChange="{Binding Parameter.ParameterModel.SmallChanges}"/> </Border> </Grid> </DataTemplate> <DataTemplate x:Key="stringTemplate"> <Grid Visibility="{Binding Parameter.ParameterModel.IsVisible, Converter={StaticResource Visibility}}"> <Grid.RowDefinitions> <RowDefinition Height="{Binding Path=RowHeight, Mode=OneWay}"/> <RowDefinition/> </Grid.RowDefinitions> <Border Grid.Row="0" Style="{StaticResource HeaderBorderStyle}" Width="{Binding Width}" Visibility="{Binding Path=HeaderVisibility, Converter={StaticResource Visibility}}"> <Label Content="{Binding Parameter.DisplayName}"/> </Border> <Border Grid.Row="1" Style="{StaticResource ItemBorderStyle}" Width="{Binding Width}" > <ComboBox ItemsSource="{Binding Path=Parameter.ParameterModel.PossibleValues}" SelectedIndex="{Binding ParameterValue, Mode=TwoWay}"> </ComboBox> </Border> </Grid> </DataTemplate> <configControl:PropertyDataTemplateSelector StringTemplate="{StaticResource stringTemplate}" DoubleTemplate="{StaticResource doubleTemplate}" x:Key="propertyDataTemplateSelector"/>
I wrote the code for the DataTemplateSelector. 我为DataTemplateSelector编写了代码。
public class PropertyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DoubleTemplate { get; set; }
public DataTemplate StringTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
DeviceModel.ParameterType devFunct = ((ParameterWrapper)item).Parameter.ParameterModel.Type;
switch (devFunct)
{
case DeviceModel.ParameterType.Double:
return DoubleTemplate;
case DeviceModel.ParameterType.String:
return StringTemplate;
default:
return null;
}
return null;
}
}
When the applications opens all the values are set fine. 当应用程序打开时,所有值均已设置好。 But when i update ParameterValue, it isn't updated on view.
但是当我更新ParameterValue时,它不会在视图上更新。 (when i output the values in console window, the values are set fine (but not in the GUI)).
(当我在控制台窗口中输出值时,这些值设置得很好(但在GUI中不是))。
What should i do to make this work. 我应该怎么做才能使这项工作。
Edit 编辑
This is the code it's bound to. 这是它绑定的代码。 Every function has a checkbox and when you change the parameter of one, all other parameters that are checked need to change.
每个功能都有一个复选框,当您更改一个参数时,所有其他已选中的参数都需要更改。
public double ParameterValue
{
get
{
return _parameter.ParameterValue;
}
set
{
Parameter.ParameterValue = value;
Console.WriteLine("ParameterValueChanged");
if (SetOthers)
{
if (_parentFunction.Checked)
{
foreach (var function in _parentFunction.FunctionWrapperList)
{
if (function.Checked)
{
foreach (var parameterWrapper in function.ParameterWrapperList)
{
if (parameterWrapper.Parameter != this.Parameter)
{
if (parameterWrapper.Parameter.ParameterModel == Parameter.ParameterModel)
{
Console.WriteLine(function.Function.Name + " " + function.Checked + " " + Parameter.ParameterValue);
parameterWrapper.SetValue(Parameter.ParameterValue);
}
}
}
}
}
}
}
Notify("ParameterValue");
}
}
private void SetValue(double parameterValue)
{
SetOthers = false;
Parameter.ParameterValue = parameterValue;
SetOthers = true;
}
The boolean SetOthers is so he won't get a stackoverflow and keeps setting itself. 布尔SetOthers是这样的,因此他不会获得stackoverflow并且会继续设置自身。
Your DataTemplateSelector won't update the DataTemplate rendering your data because a DataTemplateSelector doesn't trigger on a property change. 由于DataTemplateSelector不会在属性更改时触发,因此DataTemplateSelector不会更新呈现数据的DataTemplate。 It only choose a way to display a data according to its type (yourData.GetType()).
它仅根据其类型(yourData.GetType())选择一种显示数据的方式。
What you want is a trigger: 您想要的是一个触发器:
<ItemsControl ItemsSource="{Binding ParameterWrapperList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}">
<ContentControl.Style>
<Style TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate" Value="{StaticResource doubleTemplate}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Parameter.ParameterModel.Type}" Value="{x:Static local:DeviceModel.ParameterType.String}">
<Setter Property="ContentTemplate" Value="{StaticResource stringTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.