简体   繁体   English

Silverlight:将UIElement绑定到ListBoxItems时发生TargetInvocationException

[英]Silverlight: TargetInvocationException Occurred by Bind UIElement To ListBoxItems

I create a ListBox and bind ItemsSource to list of object: 我创建一个ListBox并将ItemsSource绑定到对象列表:

MainPage.xaml : MainPage.xaml

<Grid x:Name="LayoutRoot" Background="White"
         DataContext="{StaticResource ResourceKey=ViewModel}">

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="47*"/>
            <ColumnDefinition Width="28*"/>
        </Grid.ColumnDefinitions>

        <ListBox ItemsSource="{Binding Models}"
                     Height="200" Width="150"  Grid.Column="0">
            <ListBox.ItemTemplate>
                <DataTemplate >
                    <StackPanel>
                        <TextBlock Text="{Binding ID ,Mode=TwoWay 
                              ,UpdateSourceTrigger=PropertyChanged}"/>
                        <TextBlock Text="{Binding Name ,Mode=TwoWay 
                              ,UpdateSourceTrigger=PropertyChanged}"/>
                        <Border Child="{Binding Shape ,Mode=TwoWay 
                              ,UpdateSourceTrigger=PropertyChanged}"/>

                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <Button Content="Change Source" Height="35" Width="100" 
                Grid.Column="1">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <i:InvokeCommandAction Command="{Binding  ChangeSource}"  
                    CommandParameter="{Binding ElementName=LayoutRoot}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>

    </Grid>

Model.cs : Model.cs

public class Model
{
    private string _ID;
    private UIElement _Shape;
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set { _Name = value; }
    }

    public UIElement Shape
    {
        get { return _Shape; }
        set { _Shape = value;}
    }

    public string ID
    {
        get { return _ID; }
        set { _ID = value; }
    }
}

And

ViewModel.cs : ViewModel.cs

    public class ViewModel : INotifyPropertyChanged
    {
        Random rnd = new Random();
        List<Color> MyColors = new List<Color>() { Colors.Gray,
                               Colors.Blue, Colors.Red,
                               Colors.Green, Colors.Yellow, 
                               Colors.Orange, Colors.DarkGray };

        private List<Model> _Models;

        public List<Model> Models
        {
            get 
            {
                if (_Models == null)
                    _Models = new List<Model>();
                return _Models;
            }
            set { _Models = value; OnPropertyChanged("Models"); }
        }

        public DelegateCommand<object> ChangeSource { get; set; }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
        }


        public ViewModel()
        {
            ChangeSource = new DelegateCommand<object>(ChangeSourceCommand);

            ChangeSourceItems();
        }

        private void ChangeSourceCommand(object obj)
        {
            ChangeSourceItems();
        }
        private void ChangeSourceItems()
        {
            List<Model> tmpModels = new List<Model>();

            tmpModels.Add(new Model() { ID = "1", Name = "A", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });
            tmpModels.Add(new Model() { ID = "2", Name = "B", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });
            tmpModels.Add(new Model() { ID = "3", Name = "C", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });
            tmpModels.Add(new Model() { ID = "4", Name = "D", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });
            tmpModels.Add(new Model() { ID = "5", Name = "E", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });
            tmpModels.Add(new Model() { ID = "6", Name = "F", Shape = new Border() { Background = new SolidColorBrush(MyColors[rnd.Next(0, MyColors.Count - 1)]), Width = 10, Height = 10 } });

            Models = tmpModels;
        }
    }

Source of Models changed with click on Button . 单击Button更改模型的来源。

Question : 问题

TargetInvocationException occurred after click on Button and scroll ListView . 单击Button并滚动ListView之后发生TargetInvocationException Why? 为什么?

Exception Message : 异常消息

Exception has been thrown by the target of an invocation. 调用的目标已引发异常。

InnerException Message : InnerException消息

Value does not fall within the expected range. 值不在预期范围内。

Because you are using UIElement in model, shape created more than once and with scrolling occurred TargetInvocationException . 因为您在模型中使用UIElement ,所以多次创建形状并滚动发生TargetInvocationException

You must be inherit ListBox and override IsItemItsOwnContainerOverride method. 您必须继承ListBox并重写IsItemItsOwnContainerOverride方法。

protected override bool IsItemItsOwnContainerOverride(object item)
{
     Model model = (Model)item;

     FrameworkElement elem = (FrameworkElement)model.Shape;

     return elem.Parent != null;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM