【问题标题】:Unable to set ViewModel property when bound to UWP ComboBox绑定到 UWP ComboBox 时无法设置 ViewModel 属性
【发布时间】:2016-12-20 22:17:04
【问题描述】:

在 UWP/Template10 应用中,我们有一个绑定到 ViewModel 属性的 ComboBox。 ViewModel 属性的值在 OnNavigatedToAsync 中设置。如果我们移除 ComboBox 绑定,则 ViewModel 中的属性会被正确设置。但如果 ComboBox 绑定到该属性,则 ViewModel 属性保持为空。

XAML 看起来像这样

<ComboBox 
    Name="JobTypeComboBox" 
    ItemsSource="{x:Bind JobViewModel.JobTypes}" 
    SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>

ViewModel 看起来像这样

JobType _JobType = default(JobType);
public JobType JobType { get { return _JobType; } set { Set(ref _JobType, value); } }
public ObservableCollection<JobType> JobTypes = new ObservableCollection<JobType>(JobTypeService.GetJobTypes());

public override async Task OnNavigatedToAsync(object parameter, NavigationMode mode, IDictionary<string, object> state)
    {
            this.JobType = job.JobType;

编辑 1:转换器如下所示

public class ChangeTypeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        if (targetType.IsConstructedGenericType && targetType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
        {
            if (value == null)
            {
                return null;
            }
            targetType = Nullable.GetUnderlyingType(targetType);
        }

        if (value == null && targetType.GetTypeInfo().IsValueType)
            return Activator.CreateInstance(targetType);

        if (targetType.IsInstanceOfType(value))
            return value;

        return System.Convert.ChangeType(value, targetType);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return Convert(value, targetType, parameter, language);
    }
}

this.JobType = job.JobType; 行的执行中有6 次对转换器的调用:

使用正确的 JobType 值调用转换并返回正确的值。

ConvertBack 调用 value = null 并返回 null;

使用 value = null 调用转换并返回 null;

使用 value = null 调用转换并返回 null;

ConvertBack 调用 value = null 并返回 null;

使用 value = null 调用转换并返回 null;

所以看起来绑定将值作为 null 反弹回 ConvertBack。

Job.JobType 正确返回。如果从JobTypeComboBox 中删除绑定,则this.jobType 设置正确。当绑定添加到JobTypeComboBox 时,this.JobType 保持为空。

this.jobType绑定了this.jobType,如何设置其值?

【问题讨论】:

  • 1.集合中的 job.JobType 元素是否绑定到 ItemsSource?希望您知道它仅默认设置为 Mode=OneTime 吗? 2.ChangeTypeConverter呢?你有没有尝试过进去看看会发生什么?
  • @RTDev JobTypeComboBox 的 ItemsSource 是 ObservableCollection JobTypes。模式=双向。 job.JobType 未绑定到 ItemsSource。 JobTypeComboBox 绑定到 ItemSource。 ChangeTypeConverter 来自 Template10。它返回发送者的目标类型。如果我从绑定作业中删除 ChangeTypeConverter。JobType 设置正确。我确实需要 ChangeTypeConverter,因为 JobTypeComboBox 绑定到 JobType 而不是字符串。
  • 如果我理解正确 - 问题出在您的转换器上。尝试用这个假的来改变它(它只是假装是 covnerterter 做任何事情,但它没有,但使 xaml 编译): public class ObjectToObject : IValueConverter { public object Convert(object value, Type targetType, object参数,字符串语言){返回值; } public object ConvertBack(object value, Type targetType, object parameter, string language) { return value; } }
  • @RTDev 我实现了 ObjectToObjectConverterJobTypeComboBox SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ObjectToObjectConverter}} 但在 ViewModel 中 this.JobType 仍然为空
  • 创建非常简单的可运行代码,如果您愿意,我们可以运行它,这可以帮助我们重现问题并找出仍然存在的问题

标签: uwp uwp-xaml template10


【解决方案1】:

好吧,使用这个视图模型:

public class MainPageViewModel : ViewModelBase
{
    public MainPageViewModel()
    {
        ComboBoxItem = ComboBoxItems.First();
    }

    string _ComboBoxItem = default(string);
    public string ComboBoxItem { get { return _ComboBoxItem; } set { Set(ref _ComboBoxItem, value); } }

    public ObservableCollection<string> ComboBoxItems { get; } = new ObservableCollection<string>(new[] { "1", "2", "3", "4" });
}

还有这个 XAML:

<ComboBox x:Name="testComboBox"
            ItemsSource="{Binding ComboBoxItems}"
            RelativePanel.AlignLeftWith="parameterResizer"
            RelativePanel.Below="stateTextBox"
            SelectedItem="{Binding ComboBoxItem, Mode=TwoWay}" />

<TextBlock x:Name="testTextBlock"
            RelativePanel.AlignLeftWith="parameterResizer"
            RelativePanel.Below="testComboBox"
            Text="{Binding ComboBoxItem}" />

这件事发生了:

感谢您使用模板 10 - 虽然我认为这与 T10 无关。 :-)

【讨论】:

  • OnNavigatedToAsync 中设置值也可以。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-25
相关资源
最近更新 更多