C# e是你的UserControl,也许它根本不应该是UserControl。您可以编写一个包含XAML的数据模板并使用它,也可以为ListBox编写一个样式。如果你需要这些事件,那么用户控件是有意义的,但你可能实际上并不需要这些事件。总而言之,您的意思是我应
C# e是你的UserControl,也许它根本不应该是UserControl。您可以编写一个包含XAML的数据模板并使用它,也可以为ListBox编写一个样式。如果你需要这些事件,那么用户控件是有意义的,但你可能实际上并不需要这些事件。总而言之,您的意思是我应,c#,wpf,mvvm,nested,C#,Wpf,Mvvm,Nested,e是你的UserControl,也许它根本不应该是UserControl。您可以编写一个包含XAML的数据模板并使用它,也可以为ListBox编写一个样式。如果你需要这些事件,那么用户控件是有意义的,但你可能实际上并不需要这些事件。总而言之,您的意思是我应该始终使用DataTemplate设置我的DataContext,并且从不(除此之外)直接绑定DataContext。应该为您的模型或视图模型设计用户控件。您不应该为UserControl设计视图模型。TextBox是否具有TextBoxVie
e是你的UserControl,也许它根本不应该是UserControl。您可以编写一个包含XAML的数据模板并使用它,也可以为ListBox编写一个样式。如果你需要这些事件,那么用户控件是有意义的,但你可能实际上并不需要这些事件。总而言之,您的意思是我应该始终使用
DataTemplate
设置我的DataContext
,并且从不(除此之外)直接绑定DataContext
。应该为您的模型或视图模型设计用户控件。您不应该为UserControl设计视图模型。TextBox是否具有TextBoxViewModel?不,这有一个很好的理由。有关此反模式的实际示例以及其失败原因,请阅读。应为您的模型或视图模型设计用户控件。您不应该为UserControl设计视图模型。TextBox是否具有TextBoxViewModel?不,这有一个很好的理由。这是一个反模式的真实例子,以及它为什么会失败。
<Window x:Name="FCTWindow" x:Class="CatalogInterface.MainWindow"
xmlns:local="clr-namespace:CatalogInterface"
xmlns:vm="clr-namespace:CatalogInterface.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="532">
<Window.Resources>
<vm:MainWindowViewModel x:Key="ViewModel" />
</Window.Resources>
<Grid DataContext="{Binding Path=ViewModel.DirFilesListBoxViewModel}" x:Name="BodyGridLeft" Grid.Row="0" Grid.Column="0">
<local:ctlDirFilesListBox>
<!--
Need to access the `ItemsSource="{Binding }"` and
`SelectedItem="{Binding Path=}"` of the ListBox in
`ctlDirFilesListBox` view -->
</local:ctlDirFilesListBox>
</Window>
<UserControl x:Class="CatalogInterface.ctlDirFilesListBox"
xmlns:local="clr-namespace:CatalogInterface"
xmlns:vm="clr-namespace:CatalogInterface.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="MainControlGrid">
<ListBox SelectionChanged="ListBoxItem_SelectionChanged"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#FFFFFF"
Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" BorderThickness="0">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
<EventSetter Event="KeyDown" Handler="ListBoxItem_KeyDown"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</UserControl>
using System;
using System.Text;
namespace CatalogInterface.ViewModels
{
class MainWindowViewModel
{
public DirFilesViewModel DirFilesViewModel { get; set; }
public MainWindowViewModel()
{
DirFilesViewModel = new DirFilesViewModel();
}
}
}
public MainWindow()
{
InitializeComponent();
DataContext = new MainWindowViewModel();
}
<Window.DataContext>
<vm:MainWindowViewModel />
<Window.DataContext>
<Grid
DataContext="{Binding Source={StaticResource ViewModel}}"
>
<!-- No x:Key, just DataType: It'll be implicitly used for that type. -->
<DataTemplate DataType="{x:Type vm:DirFilesViewModel>
<local:ctlDirFilesListBox />
</DataTemplate>
<UserControl
Grid.Row="0"
Grid.Column="0"
Content="{Binding DirFilesViewModel}"
/>
<ContentControl Content="{Binding SelectedChildVM}" />
<!--
Need to access the `ItemsSource="{Binding }"` and
`SelectedItem="{Binding Path=}"` of the ListBox in
`ctlDirFilesListBox` view -->
<UserControl x:Class="CatalogInterface.ctlDirFilesListBox"
xmlns:local="clr-namespace:CatalogInterface"
xmlns:vm="clr-namespace:CatalogInterface.ViewModels"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="MainControlGrid">
<ListBox
ItemsSource="{Binding Files}"
SelectedItem="{Binding SelectedFile}"
SelectionChanged="ListBoxItem_SelectionChanged"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="#FFFFFF"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="3"
BorderThickness="0"
>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
<EventSetter Event="KeyDown" Handler="ListBoxItem_KeyDown"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</Grid>
</UserControl>
<local:ctlDirFilesListBox ItemsSource="{Binding Property}" SelectedItem="{Binding Property}" />
<ListBox SelectionChanged="ListBoxItem_SelectionChanged"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#FFFFFF"
Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" BorderThickness="0"
ItemsSource="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType=UserControl}}"
SelectedItem="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=UserControl}}">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource {x:Type ListBoxItem}}">
<EventSetter Event="MouseDoubleClick" Handler="ListBoxItem_MouseDoubleClick"/>
<EventSetter Event="KeyDown" Handler="ListBoxItem_KeyDown"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
public class ctlDirFilesListBox : UserControl
{
//...
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(ctlDirFilesListBox));
public IEnumerable ItemsSource
{
get { return (IEnumerable)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("ItemsSource", typeof(object), typeof(ctlDirFilesListBox));
public object SelectedItem
{
get { return GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
}