我正在尝试将数据类绑定到WPF中的ListView控件,但似乎无法使其正常工作。我可以在运行时绑定它并使用以下命令使其工作:
this.DataContext = DataSet;
但是,如果我在WPF / XAML中尝试以下操作,则它不起作用:
DataContext="DiscoveredItemContainer"
我尝试了各种排列,但我尝试的都没有。我可以使用运行时版本,因为它的工作原理,但是我不能让XAML正确地绑定控件。也许这不起作用,因为数据集本质上是动态的,但这只是一个想法。
我不确定代码是否有助于回答问题,但我会发布相关内容,我希望如何。我遗漏了使用声明。
这是表单的XAML
<Window x:Class="Viking.Test.DataBindTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Items="clr-namespace:Viking.Test.Discovery"
xmlns:data="clr-namespace:Viking.Test"
Title="Data Binding Test" Height="300" Width="500"
DataContext="DiscoveredItemContainer">
<DockPanel Name="_DockPanel" Height="Auto" Width="Auto">
<Menu Name="_Menu" DockPanel.Dock="Top" Height="22" Width="Auto" VerticalContentAlignment="Center" VerticalAlignment="Top">
<MenuItem Name="_File" Header="File">
<MenuItem Name="_AddOne" Header="Add One" Click="AddOne_Click" />
</MenuItem>
</Menu>
<ListView Name="listView1" Height="Auto" Width="Auto" ItemsSource="{Binding Path=DiscoveredItems}">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="Field1" DisplayMemberBinding="{Binding Field1}" Width="100" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Window>
这是与XAML
一起使用的部分类namespace Viking.Test
{
public partial class DataBindTest : Window
{
private DiscoveredItemList DiscoveredItemContainer;
public DataBindTest()
{
InitializeComponent();
DiscoveredItemContainer = new DiscoveredItemList();
// Uncomment the following line to get the databinding to work
// this.DataContext = DiscoveredItemContainer;
}
private void AddOne_Click(object sender, RoutedEventArgs e)
{
DiscoveredItemContainer.AddRandomItem();
}
} // End of Class
} // End of Namespace
The following is the class that contains the dataset
namespace Viking.Test.Discovery
{
public class DiscoveredItem
{
public DiscoveredItem()
{
}
public string Field1 { get; set; }
} // End of Class
} // End of Namespace
最后,这是将公开ObservableCollection变量以将数据绑定到类的类
namespace Viking.Test.Discovery
{
class DiscoveredItemList
{
public ObservableCollection<DiscoveredItem> DiscoveredItems { get; set; }
private Random RandomGen;
public DiscoveredItemList()
{
DiscoveredItems = new ObservableCollection<DiscoveredItem>();
RandomGen = new Random();
}
public void AddRandomItem()
{
DiscoveredItem di = new DiscoveredItem();;
di.Field1 = RandomGen.Next(1,10).ToString();
DiscoveredItems.Add(di);
}
} // End of Class
} // End of Namespace
我已经看到很多文章将控件绑定到表单上的另一个控件,或者在运行时绑定(这是我可以使它工作的方式)或绑定到静态资源。
任何关于为什么我不能让这种方法工作的见解表示赞赏。
答案 0 :(得分:3)
通过在XAML中设置DataContext,您决定实例化一个新的DiscoveredItemList,而不是绑定到代码隐藏中的那个。因此,您的代码隐藏不会直接引用DiscoveredItemList,但您始终可以按名称搜索它。
您需要做的第一件事是删除:
DataContext="DiscoveredItemContainer"
并替换为:
<Window.Resources>
<Items:DiscoveredItemList x:Key="Context"></Items:DiscoveredItemList>
</Window.Resources>
这实例化了xaml现在可以绑定到的新对象。您的列表视图应该以这种方式绑定到它:
<ListView Name="listView1" Height="Auto" Width="Auto" DataContext="{StaticResource Context}" ItemsSource="{Binding DiscoveredItems}">
...
</ListView>
您还必须在后面的代码中删除对DiscoveredItemContainer的所有引用,并且当您想要访问Items:DiscoveredItemList时,例如添加新的随机项,请执行以下操作:
private void AddOne_Click(object sender, RoutedEventArgs e)
{
var list = this.Resources["Context"] as DiscoveredItemList;
list.AddRandomItem();
}
如果您愿意,也可以存储对该项目的本地引用。
这是您复制/粘贴乐趣的完整代码。请注意,我已经测试了这个并且“它适用于我”:P
namespace Viking.Test
{
public partial class DataBindTest : Window
{
public DataBindTest()
{
InitializeComponent();
}
private void AddOne_Click(object sender, RoutedEventArgs e)
{
var list = this.Resources["Context"] as DiscoveredItemList;
list.AddRandomItem();
}
} // End of Class
} // End of Namespace
//The following is the class that contains the dataset
namespace Viking.Test.Discovery
{
public class DiscoveredItem
{
public DiscoveredItem() { }
public string Field1 { get; set; }
} // End of Class
public class DiscoveredItemList
{
public ObservableCollection<DiscoveredItem> DiscoveredItems { get; set; }
private Random RandomGen;
public DiscoveredItemList()
{
DiscoveredItems = new ObservableCollection<DiscoveredItem>();
RandomGen = new Random();
}
public void AddRandomItem()
{
DiscoveredItem di = new DiscoveredItem(); ;
di.Field1 = RandomGen.Next(1, 10).ToString();
DiscoveredItems.Add(di);
}
} // End of Class
}
XAML:
<Window x:Class="Viking.Test.DataBindTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Items="clr-namespace:Viking.Test.Discovery" xmlns:data="clr-namespace:Viking.Test" Title="Data Binding Test" Height="300" Width="500" >
<Window.Resources>
<Items:DiscoveredItemList x:Key="Context"></Items:DiscoveredItemList>
</Window.Resources>
<DockPanel Name="_DockPanel" Height="Auto" Width="Auto" >
<Menu Name="_Menu" DockPanel.Dock="Top" Height="22" Width="Auto" VerticalContentAlignment="Center" VerticalAlignment="Top">
<MenuItem Name="_File" Header="File">
<MenuItem Name="_AddOne" Header="Add One" Click="AddOne_Click" />
</MenuItem>
</Menu>
<ListView Name="listView1" Height="Auto" Width="Auto" DataContext="{StaticResource Context}" ItemsSource="{Binding DiscoveredItems}">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn Header="Field1" DisplayMemberBinding="{Binding Field1}" Width="100" />
</GridView>
</ListView.View>
</ListView>
</DockPanel>
</Window>
参考: Silverlight - Setting DataContext in XAML rather than in constructor?
答案 1 :(得分:1)
你应该替换
DataContext="DiscoveredItemContainer"
通过
DataContext="{Binding DiscoveredItemContainer}"