我有一个ObservableCollection实例绑定到一个带有两个独立数据模板的WPF列表框(一个用于显示,一个用于编辑).用于编辑的数据模板在文本框上具有单向绑定,并具有"保存"按钮.
我需要进行哪些更改才能按下"保存"按钮(将列表项置于编辑模式后),值I更改文本框以替换ObservableCollection(和显示)中的值?
我有一个容器视图,看起来像这样
<UserControl x:Class="Views.ContainerView">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewmodels:AViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:BViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:CViewModel}">
<views:MyView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:DViewModel}">
<views:MyView />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding Path=AvailableViewModels}"
SelectedItem="{Binding Path=CurrentViewModel}"
IsSynchronizedWithCurrentItem="True" />
<ContentControl Content="{Binding Path=CurrentViewModel}" />
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
我的所有视图模型都继承了BaseViewModel,因此我将视图转换为此视图
<UserControl x:Class="Views.ContainerView">
<UserControl.Resources>
<ResourceDictionary>
<DataTemplate DataType="{x:Type viewmodels:BaseViewModel}">
<views:MyView />
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<StackPanel>
<ListBox ItemsSource="{Binding Path=AvailableViewModels}"
SelectedItem="{Binding Path=CurrentViewModel}"
IsSynchronizedWithCurrentItem="True" />
<ContentControl Content="{Binding Path=CurrentViewModel}" />
</StackPanel>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
认为它只会实例化一个MyView,并在ListBox.SelectedItem更改时重新绑定viewmodel.我是否正确理解了这种行为?这是首选做法吗?当我在视图之间切换时,如何验证我没有搅拌内存?
[原创]
我有一个ListBox有它ItemsSource(这是在创建窗口后面的代码中完成)数据绑定到ObservableCollection.该ListBox则有以下DataTemplate分配对项目:
usercontrol.xaml
<ListBox x:Name="communicatorListPhoneControls"
ItemContainerStyle="{StaticResource templateForCalls}"/>
Run Code Online (Sandbox Code Playgroud)
App.xaml中
<Style x:Key="templateForCalls" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource templateRinging}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Path=hasBeenAnswered}" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource templateAnswered}"/>
</DataTrigger>
</Style.Triggers>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
当ObservableCollection使用对象更新时,这将显示在ListBox正确的初始值中DataTemplate,但是当hasBeenAnswered属性设置为true(当调试时我可以看到集合是正确的)时,DataTrigger不会重新评估,然后更新ListBox以使用正确的DataTemplate.
我INotifyPropertyChanged在我的对象中实现了Event,如果在模板中绑定了一个值,我可以看到值更新.它只是DataTrigger不会重新评估和更改为正确的模板.
我知道DataTrigger绑定是正确的,因为如果我关闭窗口并再次打开它,它将正确应用第二个datatemplate,因为hasBeenAnswered设置为true.
[编辑1]
根据Timores的评论,我尝试了以下内容:
usercontrol.xaml
<ListBox x:Name="communicatorListPhoneControls"
ItemTemplate="{StaticResource communicatorCallTemplate}"/>`
Run Code Online (Sandbox Code Playgroud)
App.xaml中:
<DataTemplate x:Key="communicatorCallTemplate">
<Label x:Name="test">Not …Run Code Online (Sandbox Code Playgroud) 我试图在我的资源字典中获取特定模板.这是我的资源字典
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:view="clr-namespace:Test.Layout.View"
xmlns:toolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><DataTemplate x:Key="LeftRightLayout">
<toolkit:DockPanel>
<view:SharedContainerView toolkit:DockPanel.Dock="Left"/>
<view:SingleContainerView toolkit:DockPanel.Dock="Right"/>
</toolkit:DockPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
但是当它到达XamlReader.Load时
private static ResourceDictionary GetResource(string resourceName)
{
ResourceDictionary resource = null;
XDocument xDoc = XDocument.Load(resourceName);
resource = (ResourceDictionary)XamlReader.Load(xDoc.ToString(SaveOptions.None));
return resource;
}
Run Code Online (Sandbox Code Playgroud)
找不到"SharedContainerView"类型,因为"clr-namespace:Test.Layout.View"是一个未知的命名空间.[线:4位置:56]
xaml datatemplate resourcedictionary xamlreader silverlight-4.0
我使用WPF RibbonControl(2010年10月版)遇到了一个小问题.我的想法是将RibbonGroup的ItemsSource属性绑定到我的viewmodel,并使用DataTemplate根据需要创建RibbonButtons.这有效,但是当您显示窗口时,它会导致绑定错误(每个按钮一个):
System.Windows.Data Error: 40 : BindingExpression path error: 'IsDropDownOpen' property not found on 'object' ''RibbonContentPresenter' (Name='PART_ContentPresenter')'. BindingExpression:Path=IsDropDownOpen; DataItem='RibbonContentPresenter' (Name='PART_ContentPresenter'); target element is 'RibbonButton' (Name=''); target property is 'NoTarget' (type 'Object')
这是一个代码片段,viewmodel被一个字符串数组所取代,但问题是相同的:
<ribbon:RibbonWindow x:Class="WpfRibbonApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ribbon="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" x:Name="RibbonWindow" Width="640" Height="480" >
<ribbon:RibbonWindow.Resources>
<x:Array x:Key="buttonArray" Type="sys:String">
<sys:String>Button 1</sys:String>
<sys:String>Button 2</sys:String>
<sys:String>Button 3</sys:String>
<sys:String>Button 4</sys:String>
<sys:String>Button 5</sys:String>
<sys:String>Button 6</sys:String>
</x:Array>
<DataTemplate x:Key="buttonTemplate">
<ribbon:RibbonButton Label="{Binding}" />
</DataTemplate>
</ribbon:RibbonWindow.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ribbon:Ribbon>
<ribbon:RibbonTab Header="Tab1">
<ribbon:RibbonGroup Header="Group1"
ItemsSource="{StaticResource …Run Code Online (Sandbox Code Playgroud) 我有一个名为item的类,它只包含两个属性.我将它们显示在屏幕上作为带有样式的按钮.这个问题涉及我如何根据IsSelected值设置按钮样式,当我想要影响的元素是样式而不是数据模板时.我已经尝试过触发器但无法使其工作.
课程如下.
public class Item : ObservableObject
{
private string _title;
private bool _isSelected;
public string Title
{
get { return _title; }
set
{
_title = value;
RaisePropertyChanged("Title");
}
}
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
RaisePropertyChanged("IsSelected");
}
}
}
Run Code Online (Sandbox Code Playgroud)
我使用数据模板在ItemsControls中显示这些项目.
<ItemsControl ItemsSource="{Binding Path=Items}" ItemTemplate="{StaticResource ResourceKey=ItemTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
使用以下样式和数据模板.
<Style x:Key="ItemButton" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="ButtonBorder" BorderThickness="2,2,2,0" BorderBrush="#AAAAAA" CornerRadius="6,6,0,0" Margin="2,20,0,0" Background="Black"> …Run Code Online (Sandbox Code Playgroud) 我正在寻找一个解决方案和/或为什么在DataTemplate中共享Binding实例的合理性.这最终归结为这样一个事实:在DataTemplate中,似乎没有办法在DependencyProperty上为每个生成的控件强制执行Binding的新实例.在所有情况下,这可能是一个公平和良好的假设,除非有ValidationRules表示特定于该控件实例的某些内容.
为了详细说明(我可以提供代码,但我不认为这是必要的),我在IsEnabled上使用DependencyPropertyDescriptor来更新属于TextBox.Text Binding,DatePicker.Text Binding或ComboBox.SelectedValue Binding的一个或多个ValidationRules.等等.当未启用控件时,验证将是不同的或不期望的.
因此,ValidationRule的IsEnabled状态特定于单个控件,因为ValidationRule集合是Binding的一部分,Binding实例正在共享 - 每个最终共享该绑定的控件将更新/覆盖之前的IsEnabled值由先前生成的控件的IsEnabled值应用.
IsEnabled只是ValidationRule中的至少两个属性之一(另一个自定义IsRequired DependencyProperty),它表示应用Binding的控件的状态.在DataTemplate之外工作时(IE:未共享Binding实例),这非常有效,并根据控件的状态忽略/更改验证逻辑.我并没有关闭替代方案,但确实认为这是一个非常灵活和动态的选项,它允许Binding实例ValidationRule和规则的控制更改状态毫不费力地发展.这也让我避免了其他明显但更丑陋的选项,比如创建几个Bindings,每个Bindings代表ValidationRule控件属性的一个组合,并在DependencyPropertyDescriptor触发时切换整个绑定.不寒而栗
任何想法都非常感谢!
我试图根据特定的布尔值更改WPF应用程序中对象的DataTemplate。当值为“ True”时,我希望数据模板为某些东西;当值为“ False”时,我希望数据模板为其他东西。
我曾尝试编写此代码,但到目前为止,我最终遇到了一个烦人的“内存不足异常”。
<DataTemplate DataType="{x:Type vm:MyObjectViewModel}">
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Visible}" Value="False">
<Setter TargetName="MainTemplateGrid" Property="Content">
<Setter.Value>
<Ellipse Width="50" Height="50" Fill="Red" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding Visible}" Value="True">
<Setter TargetName="MainTemplateGrid" Property="Content">
<Setter.Value>
<Image Source="{Binding Icon}" Opacity="{Binding Visible, Converter={StaticResource VisibilityConverter}}" />
</Setter.Value>
</Setter>
</DataTrigger>
</DataTemplate.Triggers>
<ContentControl x:Name="MainTemplateGrid" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
如果有人对如何解决此问题有任何了解,请告诉我。
我正在尝试设置将用于Line(System.Windows.Shapes.Line)对象的WPF DataTemplate .
从默认的.NET 4 WPF应用程序,我将我的Window xaml设置为:
<Window x:Class="WpfTestDataTemplates.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate DataType="{x:Type system:String}" >
<TextBlock>It's a string</TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type Line}" >
<TextBlock>It's a line</TextBlock>
</DataTemplate>
</Window.Resources>
<ListView ItemsSource="{Binding MyItems}" />
</Window>
Run Code Online (Sandbox Code Playgroud)
而背后的代码是:
using System.Collections.Generic;
using System.Windows;
using System.Windows.Shapes;
namespace WpfTestDataTemplates
{
public partial class MainWindow : Window
{
public List<object> MyItems {get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
MyItems = new List<object>();
MyItems.Add("The first string");
MyItems.Add(new …Run Code Online (Sandbox Code Playgroud) <local:LabelTemp x:Key="labelTemplate"/>
<DataTemplate x:Key="labelTemp">
<TextBlock Text="{Binding Converter={StaticResource labelTemplate},Path=Item.Items}"/>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我如何将上述Xaml代码写入Code Behind C#.我将此代码用于饼图LabelTemplate.
datatemplate ×10
wpf ×9
c# ×4
datatrigger ×2
xaml ×2
data-binding ×1
mvvm ×1
ribbon ×1
styles ×1
templating ×1
xamlreader ×1