我把MEF看成是一个可扩展性框架,除了一点之外我几乎卖得很多:
假设我要导入ViewModel和View来显示它.我认为这样做的"正确"方法是MEF部分导出ViewModel类,以及显示ViewModel的DataTemplate.例如,假设您正在构建类似Visio的应用程序,并且您想要导入形状库.每个形状都需要在Xaml中定义的View和一个将包装一些底层Model对象的ViewModel.
这可能吗?DataTemplate的Import合约会是什么样的?如何让WPF知道导入的DataTemplate?
我有一个ItemsControl,其ItemTemplate DataTemplate包含一个Button.我希望按钮上的Command绑定到ItemsControl的DataContext上的Command,而不是ItemTemplate.我认为解决方案与使用RelativeSource有关,但到目前为止我的尝试都失败了:
<ItemsControl ItemsSource="{Binding Games}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Path=GameSelectedCommand, Source={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}}"
CommandParameter="{Binding}"
Style="{StaticResource MenuButtonStyle}"
Content="{Binding Name}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
如何让Button绑定到ItemsControl的DataContext对象的GameSelectedCommand?
最近我试图在我的应用程序中重用一些UI元素.当我开始使用WPF编程时,我被告知DataTemplate是重用UI元素的最佳方式.您可以为数据实体定义模板并在任何地方使用它.听起来很不错.但是,我也发现了一些缺点,特别是在与UserControl进行比较时.
DataTemplate的另一个问题是您必须清楚DataTemplate实例本身与DataTemplate内容实例之间的区别.DataTemplate只有一个"DataTemplate实例",可能有许多DataTemplate内容实例.让我用一个例子解释一下:
<DataTemplate>
<DataTemplate.Resources>
<my:User x:key="User1"/>
</DataTemplate.Resources>
<Grid MouseLeftButtonDown="OnMouseLeftButtonDown">
<Grid.Resources>
<my:User x:key="User2"/>
</Grid.Resources>
</Grid>
</DataTemplate>
public partial class CodeBehind
{
Point mousePos = new Point();
private void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
mousePos = e.Pos...;
}
}
Run Code Online (Sandbox Code Playgroud)结果是:User1将只有一个实例,但是,一旦应用DataTemplate,将创建User2实例,这意味着如果多次应用datatemplate,User2将有许多实例.但是,与UserControl不同,字段"mousePos"不会有很多副本.如果正在应用的DataTemplate 100次,mousePos结构不会有100份,这意味着100个电网将使用的唯一一个mousePos结构字段作为同一时间,这可能会导致问题.在UserControl中,您定义的字段仅由控件使用.100个UserControl实例将具有100个字段副本.
也许我以错误的方式使用DataTemplate.任何评论表示赞赏.
最好的祝福,
扎克
我有多个视频显示它们与Mainviewmodel中的视频选择绑定.一切正常,直到我尝试将enter命令绑定到Mainviewmodel.我不知道这个的语法.目前,绑定设置为Video而不是Mainviewmodel.
错误信息:
'StartVideoCommand' property not found on 'object' ''Video'
Run Code Online (Sandbox Code Playgroud)
XAML:
<Window.Resources>
<local:MainViewModel x:Key="MainViewModel"/>
</Window.Resources>
<Grid DataContext="{StaticResource MainViewModel}">
<ListBox ItemsSource="{Binding Videos}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.InputBindings>
!!! <KeyBinding Key="Enter" Command="{Binding StartVideo}" /> !Bound to Video not to Mainviewmodel grrr
</Grid.InputBindings>
... layout stuff
<TextBlock Text="{Binding Title}" Grid.Column="0" Grid.Row="0" Foreground="White"/>
<TextBlock Text="{Binding Date}" Grid.Column="0" Grid.Row="1" Foreground="White" HorizontalAlignment="Left"/>
<TextBlock Text="{Binding Length}" Grid.Column="1" Grid.Row="1" Foreground="White" HorizontalAlignment="Right"/>
... closing tags
Run Code Online (Sandbox Code Playgroud) 有没有办法构建一个DataTemplate而不使用已弃用的 FrameworkElementFactory
或XamlReader.Load
字符串解释方法来编码(相关问题)或(另一个相关的)?
DataTemplate dt = new DataTemplate();
StackPanel sp = new StackPanel();
ComboBox cellComboBox = new ComboBox() { Visibility = Visibility.Collapsed };
CheckBox cellCheckBox = new CheckBox() { Visibility = Visibility.Collapsed };
sp.Children.Add(cellComboBox);
sp.Children.Add(cellCheckBox);
// then add the stackpanel somehow?
Run Code Online (Sandbox Code Playgroud)
更新:为什么?
这适用于可能需要多年支持的新程序.XamlReader字符串在运行时解析有一些构造函数,方法,属性......感觉很糟糕.在FrameworkElementFactory
已弃用了几个版本,但从来没有一个真正的替代品.
我有一个CheckedListBox
控件,通过添加DataTemplate
a CheckBox
到a创建ListView
.问题是我也需要列.
以下代码不显示复选框:
<ListView x:Name="lbDatabases" Height="138" Width="498" Canvas.Left="44" Canvas.Top="146">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding DbName}" Header="Databases" Width="498"/>
</GridView>
</ListView.View>
<ListView.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsActive}" Checked="AnyChange" Unchecked="AnyChange" Style="{x:Null}" Content="{Binding DbName}"
Width="{Binding CheckWidth}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Run Code Online (Sandbox Code Playgroud)
但是,如果我注释掉这段代码,一切正常,但没有列:
<ListView.View>
<GridView >
<GridViewColumn DisplayMemberBinding="{Binding DbName}" Header="Databases" Width="498"/>
</GridView>
</ListView.View>
Run Code Online (Sandbox Code Playgroud)
有没有办法拥有一切?
如何以编程方式向datatemplates添加控件?
例如.下面我创建了TextBlock和DataTemplate.
TextBlock text = new TextBlock();
DataTemplate template = new DataTemplate();
Run Code Online (Sandbox Code Playgroud)
现在我需要将TextBlock添加到DataTemplate.怎么做到这一点?
我知道后面的代码中还有其他addind数据模板的方法1.在XAML中创建数据模板并将其加载到后面的代码上2.使用XamlParser创建和添加
但我需要按照我在示例中展示的方式来做.
需要一些帮助.
我有一个列表,Games
其中只有a ID
,a Date
和a Time
.我将此列表设置为DataContext
.
然后,我有一个DataTemplate
这样的游戏:
<DataTemplate DataType="{x:Type loc:Game}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Name="dateBlock" Grid.Column="0" Grid.Row="1"
Text="{Binding Date, StringFormat=d}"></TextBlock>
<TextBlock Name="TimeBlock" Grid.Column="1" Grid.Row="1"
Text="{Binding Time}"></TextBlock>
//need to but a button here for each row
</Grid>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
要使用模板,我只是这样做:
<ListBox ItemsSource="{Binding}"></ListBox>
Run Code Online (Sandbox Code Playgroud)
我需要Button
在此列表视图中的每一行添加一个具有相同点击事件的行,但会以某种方式传递点击该按钮的游戏的ID.
我怎样才能做到这一点?我被卡住了.如果它没有意义让我知道,我会尝试更好地解释.
我将我的MenuItem的ItemsSource绑定到我的ViewModel中的ObservableCollection.这是我的xaml:
<MenuItem Header="_View"
ItemsSource="{Binding Windows}">
<MenuItem.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header"
Value="{Binding Title}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
Run Code Online (Sandbox Code Playgroud)
这部分很有用,但是现在我还想在同一个View MenuItem中添加一些静态MenuItem,用分隔符分隔.这样的东西,即使我知道这不起作用,因为我不能设置两次项目.
<MenuItem Header="_View"
ItemsSource="{Binding Windows}">
<MenuItem.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header"
Value="{Binding Title}" />
</Style>
</MenuItem.ItemContainerStyle>
<Separator />
<MenuItem Header="item 1" />
<MenuItem Header="item 2" />
</MenuItem>
Run Code Online (Sandbox Code Playgroud)
现在我通过向MenuItem添加另一个级别来创建一个解决方法,如下所示:
<MenuItem Header="_View">
<MenuItem Header="Windows"
ItemsSource="{Binding Windows}">
<MenuItem.ItemContainerStyle>
<Style>
<Setter Property="MenuItem.Header"
Value="{Binding Title}" />
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
<MenuItem Header="Load Layout" />
<MenuItem Header="Save Layout" />
</MenuItem>
Run Code Online (Sandbox Code Playgroud)
这很好用,但如果可能的话,我宁愿没有子菜单.哦,我也更喜欢在xaml而不是代码背后执行此操作.有任何想法吗?
我有一个数据模板
<Window.Resources>
<DataTemplate x:Key="BarChartItemsTemplate">
<Border Width="385" Height="50">
<Grid>
<Rectangle Name="rectangleBarChart" Fill="MediumOrchid" StrokeThickness="2" Height="40" Width="{Binding}" HorizontalAlignment="Right" VerticalAlignment="Bottom">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="4"/>
</Rectangle.LayoutTransform>
</Rectangle>
<TextBlock Margin="14" FontWeight="Bold" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding}">
<TextBlock.LayoutTransform>
<TransformGroup>
<RotateTransform Angle="90"/>
<ScaleTransform ScaleX="-1" ScaleY="1"/>
</TransformGroup>
</TextBlock.LayoutTransform>
</TextBlock>
</Grid>
</Border>
</DataTemplate>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)
我在表格上有一个按钮.我需要从dataTemplate更改矩形(scaleTransform).我如何访问上述按钮的Button_Click事件中的'rectangleBarChart'元素?
datatemplate ×10
wpf ×9
c# ×4
xaml ×4
listview ×2
bar-chart ×1
binding ×1
code-behind ×1
data-binding ×1
dynamic ×1
itemscontrol ×1
itemtemplate ×1
mef ×1
menuitem ×1
mvvm ×1
styles ×1
viewmodel ×1