C# 以下代码使用MVVM而不是主窗口
我使用的是从主窗口复制粘贴的以下代码,该窗口按预期工作C# 以下代码使用MVVM而不是主窗口,c#,wpf,xaml,mvvm,listbox,C#,Wpf,Xaml,Mvvm,Listbox,我使用的是从主窗口复制粘贴的以下代码,该窗口按预期工作 <TextBox x:Name="name1" AcceptsReturn="True" AllowDrop="True" PreviewDragEnter="DropText_PreviewDragEnter" PreviewDrop="DropText_PreviewDrop"
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
- 我已经创建了视图,它是用户控件,并将 来自主窗口XAML的代码
- 在视图模型中,我放置了用户模型的引用
- 在用户控件中,我从主窗口中输入 与事件处理程序相关,例如 DropText\u预览输入和列表框\u选择已更改
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
1。列表框出现的所有用户控件中的错误(例如,来自ListBox\u SelectionChanged System.Windows.Controls.ListBox.SelectedItems.Count>0。所选项目标记为红色,并显示以下错误
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
“无法在静态上下文中访问非静态属性SelectedItems项源”。,不确定原因是什么,因为在主窗口中它与静态相同
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
2.由于我从主窗口复制了代码,因此用户控件中存在对用户对象的引用,我认为这在MVVM中是不可接受的,我应该如何更改它?例如
var mySelectedItem = System.Windows.Controls.ListBox.SelectedItem as User;
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
或
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
这是代码。
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
我将感谢你的帮助
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
视图模型
public partial class ModelView : UserControl
{
private const string DRAG_SOURCE = "DragSource";
public ModelView()
{
InitializeComponent();
DataContext = new ModelView();
}
//Drag Over from text box to List box
private void ListBox_PreviewDrop(object sender, DragEventArgs e)
{
object dragSource = e.Data.GetData(DRAG_SOURCE);
if (dragSource != null && dragSource is TextBox)
{
(dragSource as TextBox).Text = String.Empty;
}
if (!String.IsNullOrEmpty(e.Data.GetData(DataFormats.StringFormat).ToString()) && dragSource is TextBox)
{
_UsersList.Add(new User {Name = e.Data.GetData(DataFormats.StringFormat).ToString()});
}
else
{
e.Handled = true;
}
}
}
}
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
Xaml是
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
模型视图
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
internal class ModelView
{
private ObservableCollection<User> _UsersList = new ObservableCollection<User>();
public ObservableCollection<User> UserList
{
get { return _UsersList; }
}
public void InitUsers()
{
_UsersList.Add(new User {Name = "fff"});
//Sort the User collection
ICollectionView usersView = CollectionViewSource.GetDefaultView(_UsersList);
usersView.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
}
}
内部类模型视图
{
private ObservableCollection_UsersList=new ObservableCollection();
公共ObservableCollection用户列表
{
获取{return\u UsersList;}
}
公共用户()
{
_添加(新用户{Name=“fff”});
//对用户集合进行排序
ICollectionView usersView=CollectionViewSource.GetDefaultView(\u UsersList);
usersView.SortDescriptions.Add(新的SortDescription(“Name”,ListSortDirection.升序));
}
}
您必须通过
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
yourListBoxName.SelectedItems.Count > 0
您无法通过访问它
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
System.Windows.Controls.ListBox.SelectedItems.Count
同样适用于
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
var mySelectedItem = System.Windows.Controls.ListBox.SelectedItem as User;
请使用以下命令
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
var mySelectedItem = yourListBoxName.SelectedItem as User;
您必须通过以下方式访问列表框:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
yourListBoxName.SelectedItems.Count > 0
您无法通过访问它
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
System.Windows.Controls.ListBox.SelectedItems.Count
同样适用于
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
var mySelectedItem = System.Windows.Controls.ListBox.SelectedItem as User;
请使用以下命令
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
var mySelectedItem = yourListBoxName.SelectedItem as User;
您已经有两个答案解释了为什么第一个问题发生在中。以下几点是@Will在评论中说的MVVM实现混乱的地方,我可以在您的代码中看到:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
用户列表
是一个模型,与模型视图模型一样用户控制
,而用户控制
是一个视图,与窗口
或页面
等没有区别。它们都是视图。即使我们同意称它为视图模型,它也违反了MVVM原则无处不在,因为视图模型不应该引用视图/UI控件对象不是直接回答你的问题,但我希望你对MVVM模式有一个更好的了解。你已经有两个答案解释了第一个问题发生的原因。下面几点是@Will在评论中说的MVVM实现一团糟,我可以在你的代码中看到:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
用户列表
是一个模型,与模型视图模型一样用户控制
,而用户控制
是一个视图,与窗口
或页面
等没有区别。它们都是视图。即使我们同意称它为视图模型,它也违反了MVVM原则无处不在,因为视图模型不应该引用视图/UI控件对象不是直接回答您的问题,但我希望您对MVVM模式有更好的了解。@phil正确地指出,您不能像这样访问
列表框:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
System.Windows.Controls.ListBox
string selectedItemName = SelectedItem.Name;
他没有提到的是,如果你在使用MVVM,你根本不应该访问列表框
。很明显,你现在没有使用MVVM,但如果你想,我建议你仔细阅读它,这样你就可以从中获得全部好处。拥有视图和视图模型并不意味着你在使用MVVM
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
在MVVM中,我们操作数据,而不是UI控件。因此,您需要在视图模型中创建一个SelectedItem
属性,并将其绑定到列表框。SelectedItem
属性,然后您将始终有权访问所选项目:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
public User SelectedItem { get; set; } // Implement INotifyPropertyChanged here
...
<ListBox ItemsSource="{Binding YourCollection}" SelectedItem="{Binding SelectedItem}"/>
@phil正确地指出,您不能像这样访问列表框
:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
System.Windows.Controls.ListBox
string selectedItemName = SelectedItem.Name;
他没有提到的是,如果你在使用MVVM,你根本不应该访问列表框
。很明显,你现在没有使用MVVM,但如果你想,我建议你仔细阅读它,这样你就可以从中获得全部好处。拥有视图和视图模型并不意味着你在使用MVVM
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
在MVVM中,我们操作数据,而不是UI控件。因此,您需要在视图模型中创建一个SelectedItem
属性,并将其绑定到列表框。SelectedItem
属性,然后您将始终有权访问所选项目:
<TextBox x:Name="name1"
AcceptsReturn="True"
AllowDrop="True"
PreviewDragEnter="DropText_PreviewDragEnter"
PreviewDrop="DropText_PreviewDrop"
PreviewMouseDown="DropText_PreviewMouseDown"
HorizontalAlignment="Left" Height="20" Margin="360,70,0,0" TextWrapping="Wrap" Text=""
VerticalAlignment="Top" Width="70"/>
public User SelectedItem { get; set; } // Implement INotifyPropertyChanged here
...
<ListBox ItemsSource="{Binding YourCollection}" SelectedItem="{Binding SelectedItem}"/>
由于Im使用拖放(请参见文本框xaml)我需要将DropText\u PreviewDragEnter等事件的代码放在用户控件中,否则我会出错!!!,如果你不想破坏mvvm,你会怎么做,请提供示例任何事件都可以通过将其包装在附加属性中以mvvm的方式处理…这是一个简单的例子。在@Sheridan这里,我不能同意你的观点。Model
s和