Я пытаюсь связать класс данных с элементом управления ListView в WPF, но не могу заставить его работать. Я могу связать его во время выполнения и заставить его работать, используя следующее:Привязка элемента управления к классу данных с использованием WPF/XAML
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
Я видел большое количество статей привязки элемента управления к другому элементу управления, который находится в форме, или привязки во время выполнения (как я могу заставить это работать), или привязки к статическим ресурсам.
Любое понимание того, почему я не могу получить такой подход к работе, ценится.
Спасибо.
Марк
Блестящий, отлично работает. Мне просто нужно было изменить эти несколько строк, как вы заявляли, компилировали и запускали проект, а затем bam! Отлично работает! Наконец, это либо метод предпочтительнее, чем другой? – lordhog
Это действительно вопрос предпочтения. Но в целом, чем чище будет разделение между пользовательским интерфейсом и «деловой» логикой, тем лучше будет. В этом смысле ваш вид (код XAML) не должен знать и не заботится о том, каков его контекст данных, до тех пор, пока DiscoveredItems существует где-то там. Поэтому я предлагаю вам отменить все, что я только что написал, установить DiscoveredItemContainer как общедоступное свойство, а затем установить this.DataContext = DiscoveredItemContainer. В конечном итоге это будет меньше хлопот. – bufferz
Вы также получите средний уровень между вашим пользовательским интерфейсом и классом DiscoveredItemsContainer. Это будет ViewModel. Если вы еще не изучили мир MVVM, пожалуйста, возьмите некоторых из них, чтобы посмотреть это отличное видео: http://blog.lab49.com/archives/2650 Ваш WPF и навыки привязки будут сниматься как ракета один раз вы получите MVVM, и вы будете писать более чистый код, чем когда-либо. – bufferz