值不在预期范围内

wang_peng 长春联恒科技 .net 高级软件工程师  2011-01-11 08:52:54
在xaml文件中放了一个ListBox名曰:listBox1,一个ContentPresenter名曰:ContentPresenter
想实现作用:选择ListBox的列表项,显示在ContentPresenter中
代码如下相当简单和少的代码量:
1.初始化ListBox列表项
public MainPage()
{
InitializeComponent();
for (int i = 0; i < 40; i++)
{
CheckBox chk = new CheckBox();
chk.Content = i;
chk.Tag = i;
this.listBox1.Items.Add(chk);
}
}
2.选择事件
private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
object o = ((ListBox)sender).SelectedItem;
CheckBox chk = o as CheckBox;
this.ContentPresenter.Content = chk;
}
当执行到this.ContentPresenter.Content = chk时,报错“值不在预期的范围内”
...全文
1648 点赞 收藏 6
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
wang_peng 2011-01-25
我的目的是为了自己写combobx控件,
思路就是在xaml中放一个按钮,一个popup,一个ContentPresenter
实例化控件时动态创建ListBox及填充数据,ListBox放在popup中
点按钮时弹出popup也就出现了ListBox

选择ListBox的中数据显示在ContentPresenter中
当ListBox列表项入一个的控件时(如CheckBox ),选择项目时就出现我上面出现的问题
ListBox背后的代码,我也看了,没看明白.很多东西都被封装了起来.
只能看个大概思路,问题还没解决,头痛啊.
不过要感谢各位的关心
回复
namhyuk 2011-01-11
最接近你要的效果,我用了一个简单的MVVM模式,主要是说明数据为中心,和数据怎样显示可以用DataTemplate来搞~~~


<UserControl x:Class="SilverlightApplication2.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.Resources>
<DataTemplate x:Key="chkBoxTemplate">
<CheckBox Content="{Binding Content, Mode=OneWay}" IsChecked="{Binding Checked, Mode=TwoWay}" />
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding Path=Items}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox ItemTemplate="{StaticResource chkBoxTemplate}" ItemsSource="{Binding}" />
<ContentControl Grid.Column="1" ContentTemplate="{StaticResource chkBoxTemplate}" Content="{Binding Path=CurrentItem}" />
</Grid>
</UserControl>



public class MyState : INotifyPropertyChanged
{
private bool? _checked;
public bool? Checked
{
get
{
return _checked;
}
set
{
_checked = value;
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Checked"));
}
}

public string Content { get; set; }

public event PropertyChangedEventHandler PropertyChanged;
}
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();

this.Loaded += (s, e) =>
{
this.DataContext = this;
};
}

private List<MyState> _items;

public ICollectionView Items
{
get
{
if (_items == null)
{
_items = new List<MyState>();
for (int i = 0; i < 40; i++)
_items.Add(new MyState { Checked = false, Content = i.ToString() });
}
// 引用System.Windows.Data.dll
return new PagedCollectionView(_items);
}
}
}


代码看起来复杂,但这种方式会在实际的开发中更有效,更易于维护。
回复
namhyuk 2011-01-11
我不理解为什么你要把ListBox项里的CheckBox复制到另一个ContentCotrol(或你这里的ContentPresenter)里。

ListBox这些都只是控件,它呈现的背后数据才是我们关心的。

还有ContentPresenter一般在自定义Control Template才用。
回复
Sunpire 2011-01-11
1楼2楼很好很强大。支持!

3楼只是想针对问题解决问题,不可取。
回复
windhuan 2011-01-11
上面代码有误
((ListBox)sender).Items.Remove
回复
windhuan 2011-01-11
值不在预期的范围内

是因为一个对象被多次显示在UI上
object o = ((ListBox)sender).SelectedItem;
CheckBox chk = o as CheckBox;
this.ContentPresenter.Content = chk;

像这里 chk 已经在Listbox中显示,你再将它赋值到ContentPresenter, 即被多次显示,这是不允许的

将代码修改如下
object o = ((ListBox)sender).SelectedItem;
((ListBox)sender).Remove(o);
CheckBox chk = o as CheckBox;
this.ContentPresenter.Content = chk;
回复
相关推荐
发帖
WPF/Silverlight
创建于2007-09-28

8590

社区成员

WPF/Silverlight相关讨论
申请成为版主
帖子事件
创建了帖子
2011-01-11 08:52
社区公告
暂无公告