C# 在XAML中使用简单的数据绑定
我有一个字符串列表,我想在TabControl的不同选项卡中的几个ComboBox控件中使用这些字符串。字符串列表位于公共可观察集合中。问题是,我无法在XAML文件的部分中显示此集合。以下是全新应用程序中的代码:C# 在XAML中使用简单的数据绑定,c#,wpf,C#,Wpf,我有一个字符串列表,我想在TabControl的不同选项卡中的几个ComboBox控件中使用这些字符串。字符串列表位于公共可观察集合中。问题是,我无法在XAML文件的部分中显示此集合。以下是全新应用程序中的代码: using System; using System.Collections.ObjectModel; using System.Windows; namespace APX_Interface { public partial class MainWindow : Wind
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace APX_Interface
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public ObservableCollection<String> MyStringList; // not initialized yet
public class NameList : ObservableCollection<String>
{
public NameList() : base()
{
Add("Willam");
Add("Isak");
Add("Victor");
Add("Jules");
}
}
}
}
使用系统;
使用System.Collections.ObjectModel;
使用System.Windows;
名称空间APX_接口
{
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
public observeCollection MyStringList;//尚未初始化
公共类名称列表:ObservableCollection
{
公共名称列表():base()
{
添加(“威廉”);
添加(“Isak”);
添加(“胜利者”);
添加(“朱尔斯”);
}
}
}
}
以下是XAML:
Window x:Class="APX_Interface.MainWindow"
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"
xmlns:local="clr-namespace:APX_Interface"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<local:MyStringList x:Key="Strings"/>
<local:NameList x:Key="Names"/>
</Window.Resources>
<Grid>
</Grid>
windowx:Class=“APX\u接口.主窗口”
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"
xmlns:local=“clr命名空间:APX_接口”
mc:Ignorable=“d”
Title=“MainWindow”Height=“450”Width=“800”>
当我键入local:时,自动完成显示的唯一内容是App。编译代码时,我会遇到如下错误:
<Window.Resources>
<local:NameList x:Key="Names"/>
</Window.Resources>
...
<ComboBox ItemsSource="{StaticResource Names}" .../>
<ComboBox ItemsSource="{x:Static local:MainWindow.NameList}" .../>
<Window.Resources>
<local:StringCollectionINCC x:Key="Strings">
<sys:String>Willam</sys:String>
<sys:String>Isak</sys:String>
<sys:String>Victor</sys:String>
<sys:String>Jules</sys:String>
</local:StringCollectionINCC>
<x:Static Member="local:MyValues.NameList" x:Key="Names"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource Strings}}" />
<ListBox Grid.Column="1" ItemsSource="{Binding Mode=OneWay, Source={StaticResource Names}}" />
</Grid>
错误XML命名空间“clr命名空间:APX_接口”中不存在标记“MyStringList”
错误XDG0008命名空间“clr命名空间:APX_接口”中不存在名称“MyStringList”
错误XLS0414未找到类型“local:MyStringList”。验证是否缺少部件引用,以及是否已生成所有引用的部件。
类名称列表也有相同的错误
在看了很多例子和其他讨论之后,我无法指出我遗漏了什么
谢谢你的建议,不幸的是我们还没有解决这个问题。
我在这里发布了代码以及建议的更改和我的评论:
using System;
using System.Collections.ObjectModel;
using System.Windows;
namespace APX_Interface
{
public class NameList : ObservableCollection<String>
// This class is now THE ONLY thing visible in <Window.Resources>
// but not any instance of the class.
{
public NameList() : base()
{
}
}
public partial class MainWindow : Window
{
// This instance of the class is NOT visible in <Window.Resources> ???
public NameList MyNames { get { return _names;} }
// nor is this
public ObservableCollection<String> MyNumbers { get { return _numbers; } }
// nope
public NameList _names = null;
//Neither this one
public ObservableCollection<String> _numbers = null;
public MainWindow()
{
InitializeComponent();
// this doesn't make any difference
DataContext = this;
_names = new NameList();
_names.Add("fellow"); // populate dynamically
var _nr = new string[] // static strings
{
"One",
"Two",
"etc.",
};
_numbers = new ObservableCollection<string>(_nr);
}
}
}
使用系统;
使用System.Collections.ObjectModel;
使用System.Windows;
名称空间APX_接口
{
公共类名称列表:ObservableCollection
//该类现在是中唯一可见的对象
//但不是该类的任何实例。
{
公共名称列表():base()
{
}
}
公共部分类主窗口:窗口
{
//类的此实例在???中不可见???
公共名称列表MyNames{get{return}
//这也不是
公共ObservableCollection MyNumbers{get{return}
//没有
公共名称列表_names=null;
//这两个都不是
公共可观测集合_numbers=null;
公共主窗口()
{
初始化组件();
//这没什么区别
DataContext=this;
_名称=新名称列表();
_names.Add(“fellor”);//动态填充
var _nr=新字符串[]//静态字符串
{
“一个”,
“两个”,
“等等”,
};
_数字=新的可观察到的集合(_nr);
}
}
}
您已将名称列表
声明为MainWindow类中的嵌套类。把它搬出去
除此之外,您不需要在主窗口中声明MyStringList
字段,并且名称列表也不需要是一个可观察的集合,因为您显然从未在集合初始化后向集合添加或从集合中移除元素
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class NameList : List<String>
{
public NameList()
{
Add("Willam");
Add("Isak");
Add("Victor");
Add("Jules");
}
}
该资源:
<coll:StringCollection x:Key="Names">
<sys:String>Willam</sys:String>
<sys:String>Isak</sys:String>
<sys:String>Victor</sys:String>
<sys:String>Jules</sys:String>
</coll:StringCollection>
并将其分配给主窗口的DataContext
private readonly ViewModel viewModel = new ViewModel();
public MainWindow()
{
InitializeComponent();
DataContext = viewModel;
viewModel.NameList.Add("Willam");
viewModel.NameList.Add("Isak");
viewModel.NameList.Add("Victor");
viewModel.NameList.Add("Jules");
}
在XAML中,像这样绑定组合框
<ComboBox ItemsSource="{Binding NameList}" .../>
EDIt2:另一种非常简单的方法可能是静态成员,例如在MainWindow类中,如
public partial class MainWindow : Window
{
...
public static List<string> NameList { get; } = new List<string>
{
"Willam", "Isak", "Victor", "Jules"
};
}
公共部分类主窗口:窗口
{
...
公共静态列表名称列表{get;}=新列表
{
“威廉”,“伊萨克”,“维克多”,“朱尔斯”
};
}
使用的方法如下:
<Window.Resources>
<local:NameList x:Key="Names"/>
</Window.Resources>
...
<ComboBox ItemsSource="{StaticResource Names}" .../>
<ComboBox ItemsSource="{x:Static local:MainWindow.NameList}" .../>
<Window.Resources>
<local:StringCollectionINCC x:Key="Strings">
<sys:String>Willam</sys:String>
<sys:String>Isak</sys:String>
<sys:String>Victor</sys:String>
<sys:String>Jules</sys:String>
</local:StringCollectionINCC>
<x:Static Member="local:MyValues.NameList" x:Key="Names"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource Strings}}" />
<ListBox Grid.Column="1" ItemsSource="{Binding Mode=OneWay, Source={StaticResource Names}}" />
</Grid>
如果您需要使用local:NameList,那么您必须按照上面的答案进行操作。如果您需要使用MyStringList属性,则必须执行以下操作:
public partial class MainWindow : Window
{
public ObservableCollection<string> _myStringList=new ObservableCollection<string>(); // not initialized yet
public ObservableCollection<string> MyStringList
{
get
{
return _myStringList;
}
set
{
_myStringList = value;
}
}
public MainWindow()
{
InitializeComponent();
fillCombo();
DataContext = this;
}
public void fillCombo()
{
MyStringList.Add("Willam");
MyStringList.Add("Isak");
MyStringList.Add("Victor");
MyStringList.Add("Jules");
}
}
公共部分类主窗口:窗口
{
public observeCollection _myStringList=new observeCollection();//尚未初始化
公共可观测集合MyStringList
{
得到
{
返回_myStringList;
}
设置
{
_myStringList=值;
}
}
公共主窗口()
{
初始化组件();
fillCombo();
DataContext=this;
}
公共void fillCombo()
{
MyStringList.Add(“Willam”);
MyStringList.Add(“Isak”);
MyStringList.Add(“Victor”);
添加(“朱尔斯”);
}
}
在XML中:
<ComboBox ItemsSource="{Binding MyStringList}" Name="comboBox1" Margin="34,56,0,0"
VerticalAlignment="Top"
Width="200"/>
注意:您还可以在项目中创建usercontrol或customcontrol,然后使用所需元素设计控件。之后,您可以使用创建的控件来控制您想要的任何XML页面。有几种解决方案,但要选择一种特定的解决方案,您需要给出任务的更多细节 如果需要一个简单的字符串集合,则不需要创建自己的类。 正如@Clements所写的,更好地使用StringCollection 如果需要更改集合的功能(INotifyCollectionChanged接口),可以添加自己的类。 但是您需要在名称空间中构建它,一个
<Window.Resources>
<local:StringCollectionINCC x:Key="Strings">
<sys:String>Willam</sys:String>
<sys:String>Isak</sys:String>
<sys:String>Victor</sys:String>
<sys:String>Jules</sys:String>
</local:StringCollectionINCC>
<x:Static Member="local:MyValues.NameList" x:Key="Names"/>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource Strings}}" />
<ListBox Grid.Column="1" ItemsSource="{Binding Mode=OneWay, Source={StaticResource Names}}" />
</Grid>
<ListBox Grid.Column="1" ItemsSource="{x:Static local:MyValues.NameList}" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{x:Static local:MyValues.NameList}" />
<StackPanel Grid.Column="1">
<TextBox x:Name="tbNew"/>
<Button Content="Add" Click="Button_Click"/>
</StackPanel>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
MyValues.NameList.Add(tbNew.Text);
}
<Window.Resources>
<local:StringCollectionINCC x:Key="Strings">
<sys:String>Willam</sys:String>
<sys:String>Isak</sys:String>
<sys:String>Victor</sys:String>
<sys:String>Jules</sys:String>
</local:StringCollectionINCC>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource Strings}}" />
<StackPanel Grid.Column="1">
<TextBox x:Name="tbNew"/>
<Button Content="Add" Click="Button_Click"/>
</StackPanel>
</Grid>
private void Button_Click(object sender, RoutedEventArgs e)
{
StringCollectionINCC list = (StringCollectionINCC)Resources["Strings"];
list.Add(tbNew.Text);
}
/// <summary>Executing Delegate.</summary>
/// <param name="parameter">Command parameter.</param>
public delegate void ExecuteHandler(object parameter);
/// <summary>CanExecuting Delegate.</summary>
/// <param name="parameter">Command parameter.</param>
/// <returns><see langword="true"/> - if command execution is allowed.</returns>
public delegate bool CanExecuteHandler(object parameter);
/// <summary>A class implementing the ICommand interface for creating WPF commands.</summary>
public class RelayCommand : ICommand
{
private readonly CanExecuteHandler _canExecute = CanExecuteDefault;
private readonly ExecuteHandler _execute;
private readonly EventHandler _requerySuggested;
public event EventHandler CanExecuteChanged;
/// <summary>The constructor of the command.</summary>
/// <param name="execute">Command Executable Method.</param>
/// <param name="canExecute">Team Status Method.</param>
public RelayCommand(ExecuteHandler execute, CanExecuteHandler canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
_requerySuggested = (o, e) => Invalidate();
CommandManager.RequerySuggested += _requerySuggested;
}
/// <summary>The method of invoking an event about a change in command status.</summary>
public void Invalidate() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
public bool CanExecute(object parameter) => _canExecute == null ? true : _canExecute.Invoke(parameter);
public void Execute(object parameter) => _execute?.Invoke(parameter);
/// <summary>Default CanExecute Method/</summary>
/// <param name="parameter">>Command parameter.</param>
/// <returns>Is always <see langword="true"/>.</returns>
public static bool CanExecuteDefault(object parameter) => true;
}
/// <summary>ViewModel</summary>
public class MainVM
{
public ObservableCollection<string> NameList { get; }
= new ObservableCollection<string>()
{
"Willam",
"Isak",
"Victor",
"Jules"
};
private RelayCommand _addCommand;
public RelayCommand AddCommand => _addCommand
?? (_addCommand = new RelayCommand(AddMethod, AddCanMethod));
/// <summary>A method that checks that a parameter can be cast to
/// a string and that string is not empty.</summary>
/// <param name="parameter">Command parameter.</param>
/// <returns><see langword="true"/> - if the conditions are met.</returns>
private bool AddCanMethod(object parameter)
=> parameter is string val
&& !string.IsNullOrWhiteSpace(val);
/// <summary>Method to add a value to a collection.</summary>
/// <param name="parameter">Valid command parameter.</param>
private void AddMethod(object parameter)
=> NameList.Add((string) parameter);
}
/// <summary>Contains all ViewModel. In this case, only one MainVM.</summary>
public class Locator
{
public MainVM MainVM { get; } = new MainVM();
}
<Application.Resources>
<local:Locator x:Key="Locator"/>
</Application.Resources>
<Window ....
DataContext="{Binding MainVM, Mode=OneWay, Source={StaticResource Locator}}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ListBox ItemsSource="{Binding NameList}" />
<StackPanel Grid.Column="1">
<TextBox x:Name="tbNew"/>
<Button Content="Add"
Command="{Binding AddCommand, Mode=OneWay}"
CommandParameter="{Binding Text, ElementName=tbNew}"/>
</StackPanel>
</Grid>
</Window>