我有一个自定义的Treeview控件,并且将控件属性SelectedTreeItem绑定到viewmodel中的对象SelectedItem属性,当将SelectedItem类型设置为object时,没有红色验证边框,但是将SelectedItem类型用作Model时我得到这个红色边框。 取消选择一个从控件到视图模型返回null的项目后,就会出现此边框。
通过一些研究,我发现这是由于两者的类型不同,并且需要在绑定中使用转换器,所以我使用了转换器
XAML:
SelectedTreeItem="{Binding SelectedItem, Mode=TwoWay,Converter={StaticResource selectedItemConverter}}"
ViewModel属性:
private Model selectedItem;
public Model SelectedItem
{
get
{
return selectedItem;
}
set
{
selectedItem = value;
this.RaisePropertyChanged(() => this.SelectedItem);
}
}
转换器:
public class SelectedItemConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
object obj = null;
obj = (value as object);
return obj;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
即使使用此转换器,我也会遇到相同的问题 ,我做错了什么?red line
答案 0 :(得分:0)
尝试使用ValueConverter绑定到TreeView控件的选定项没有任何意义,因为SelectedItem是只读属性。
尽管可以使用Behavior
类来实现这种功能,例如
public class perTreeViewHelper : Behavior<TreeView>
{
public object BoundSelectedItem
{
get => GetValue(BoundSelectedItemProperty);
set => SetValue(BoundSelectedItemProperty, value);
}
public static readonly DependencyProperty BoundSelectedItemProperty =
DependencyProperty.Register("BoundSelectedItem",
typeof(object),
typeof(perTreeViewHelper),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnBoundSelectedItemChanged));
private static void OnBoundSelectedItemChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (args.NewValue is perTreeViewItemViewModelBase item)
item.IsSelected = true;
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged;
}
protected override void OnDetaching()
{
AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged;
base.OnDetaching();
}
private void OnTreeViewSelectedItemChanged(object obj, RoutedPropertyChangedEventArgs<object> args)
{
BoundSelectedItem = args.NewValue;
}
}
然后可以将其添加到xaml中用于视图的标准TreeView控件中。
<TreeView Grid.Column="0" ItemsSource="{Binding RootItemVms}">
<i:Interaction.Behaviors>
<vhelp:perTreeViewHelper BoundSelectedItem="{Binding SelectedItem}" />
</i:Interaction.Behaviors>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:ItemVm}" ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<CheckBox
VerticalAlignment="Center"
Focusable="False"
IsChecked="{Binding IsChecked, Mode=TwoWay}" />
<TextBlock
Margin="4,0,8,0"
VerticalAlignment="Center"
Text="{Binding Caption}" />
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
有关如何在WPF / MVVM中处理TreeView控件的更多详细讨论,请看我的blog post。
答案 1 :(得分:-1)
该问题是由于从控件向视图模型返回null时,在ConvertBack中未进行转换。
public class SelectedItemConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value as Model;
}
}