绑定到UWP组合框时无法设置ViewModel属性

绑定到UWP组合框时无法设置ViewModel属性,uwp,uwp-xaml,template10,Uwp,Uwp Xaml,Template10,在UWP/Template10应用程序中,我们有一个绑定到ViewModel属性的组合框。ViewModel属性的值在OnNavigatedToAsync中设置。如果删除组合框绑定,则ViewModel中的属性将被适当设置。但是,如果组合框绑定到属性,则ViewModel属性将保持空 XAML看起来像这样 <ComboBox Name="JobTypeComboBox" ItemsSource="{x:Bind JobViewModel.JobTypes}"

在UWP/Template10应用程序中,我们有一个绑定到ViewModel属性的组合框。ViewModel属性的值在OnNavigatedToAsync中设置。如果删除组合框绑定,则ViewModel中的属性将被适当设置。但是,如果组合框绑定到属性,则ViewModel属性将保持空

XAML看起来像这样

<ComboBox 
    Name="JobTypeComboBox" 
    ItemsSource="{x:Bind JobViewModel.JobTypes}" 
    SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
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;
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);
    }
}

ViewModel如下所示

<ComboBox 
    Name="JobTypeComboBox" 
    ItemsSource="{x:Bind JobViewModel.JobTypes}" 
    SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
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;
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);
    }
}
JobType\u JobType=默认值(JobType);
PublicJobType JobType{get{return{uJobType;}set{set(ref{uJobType,value);}
public ObservableCollection JobTypes=新的ObservableCollection(JobTypeService.GetJobTypes());
NavigatedToAsync上的公共重写异步任务(对象参数、NavigationMode模式、IDictionary状态)
{
this.JobType=job.JobType;
编辑1:转换器如下所示

<ComboBox 
    Name="JobTypeComboBox" 
    ItemsSource="{x:Bind JobViewModel.JobTypes}" 
    SelectedItem="{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ChangeTypeConverter}}"/>
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;
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);
    }
}
公共类ChangeTypeConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、字符串语言)
{
if(targetType.IsConstructedGenericType&&targetType.GetGenericTypeDefinition().Equals(typeof(null)))
{
如果(值==null)
{
返回null;
}
targetType=Nullable.GetUnderlinegType(targetType);
}
if(value==null&&targetType.GetTypeInfo().IsValueType)
返回Activator.CreateInstance(targetType);
if(targetType.IsInstanceOfType(值))
返回值;
返回系统.Convert.ChangeType(值,targetType);
}
公共对象转换回(对象值、类型targetType、对象参数、字符串语言)
{
返回转换(值、目标类型、参数、语言);
}
}
在执行行
this.JobType=job.JobType;
时,有6个对转换器的调用:

使用JobType的正确值调用Convert,并返回正确的值

使用value=null调用ConvertBack并返回null

使用value=null调用Convert并返回null

使用value=null调用Convert并返回null

使用value=null调用ConvertBack并返回null

使用value=null调用Convert并返回null

因此,看起来绑定将值作为null反弹回ConvertBack

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


JobTypeComboBox
绑定到此.jobType时,如何设置该.jobType的值?

使用此视图模型:

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" });
}
public类MainPageViewModel:ViewModelBase
{
公共MainPageViewModel()
{
ComboBoxItem=ComboBoxItems.First();
}
字符串_ComboBoxItem=默认值(字符串);
公共字符串ComboBoxItem{get{return}ComboBoxItem;}set{set(ref{uComboboxItem,value);}
PublicObservableCollection ComboBoxItems{get;}=新的ObservableCollection(新[]{“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无关。:-

好的,使用此视图模型:

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" });
}
public类MainPageViewModel:ViewModelBase
{
公共MainPageViewModel()
{
ComboBoxItem=ComboBoxItems.First();
}
字符串_ComboBoxItem=默认值(字符串);
公共字符串ComboBoxItem{get{return}ComboBoxItem;}set{set(ref{uComboboxItem,value);}
PublicObservableCollection ComboBoxItems{get;}=新的ObservableCollection(新[]{“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无关。:-

1.集合中的job.JobType元素是否绑定到ItemsSource?希望您知道它默认设置为Mode=OneTime?2.ChangeTypeConverter如何?您尝试过进入它并查看那里发生了什么吗?@RTDev JobTypeComb的ItemsSourceoBox是ObservableCollection JobTypes.Mode=TwoWay。job.JobType未绑定到ItemsSource。JobTypeComboBox绑定到ItemSource。ChangeTypeConverter来自Template10。它返回发件人的目标类型。如果我从绑定作业中删除ChangeTypeConverter,则JobType设置正确。我确实需要ChangeTypeConverter作为JobTypeComboBox绑定到JobType而不是字符串。如果我理解正确,问题在于您的转换器。请尝试使用此伪代码更改它(它只不过是假装是Cownerter,做任何事情,但它不做,但使xaml编译):公共类ObjectToObject:IValueConverter{public object Convert(对象值,类型targetType,对象参数,字符串语言){return value;}公共对象ConvertBack(对象值,类型targetType,对象参数,字符串语言){return value;}@RTDev I实现了
ObjectToObject Converter
JobTypeComboBox SelectedItem=“{x:Bind JobViewModel.JobType,Mode=TwoWay,Converter={StaticResource ObjectToObject Converter}”
但是在ViewModel
中,这个.JobType
仍然是空的创建非常简单的可运行的代码片段,如果您愿意,我们可以运行它,这可以帮助我们重现问题并找出仍然错误的地方1.集合中的job.JobType元素是否绑定到ItemsSource?希望您知道默认情况下它设置为Mode=OneTime?2.wChangeTypeConverter怎么样?你试过进入它并看看那里发生了什么吗?@RTDev作业类型组合框的ItemsSource是ObservableCollection作业类型。Mode=TwoWay。job.JobType没有绑定到ItemsSource.JobTypeComboBox