C# 如何从DataTemplate访问ObservableCollection
我想从新的C# 如何从DataTemplate访问ObservableCollection,c#,wpf,C#,Wpf,我想从新的DataTemplate访问我的项目ObservableCollection,我的实际DataTemplate有什么问题 这是我的xaml: <Window x:Class="Data.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmln
DataTemplate
访问我的项目ObservableCollection
,我的实际DataTemplate
有什么问题
这是我的xaml:
<Window x:Class="Data.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Data"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- Icon template style -->
<DataTemplate x:Key="iconTemplate">
<ListView ItemsSource="{Binding Items}">
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Rectangle Height="32" Width="32" Fill="Blue"/>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</DataTemplate>
<!-- Detailed list style-->
<DataTemplate x:Key="listTemplate">
</DataTemplate>
<Style x:Key="selectableContentStyle" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TTemplate}" Value="Icon">
<Setter Property="ContentTemplate" Value="{StaticResource iconTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TTemplate}" Value="List">
<Setter Property="ContentTemplate" Value="{StaticResource listTemplate}" />
</DataTrigger>
<!-- Other listview styles -->
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Command="{Binding ChangeView}">Change</Button>
</StackPanel>
<ContentControl Style="{StaticResource selectableContentStyle}" Margin="112,66,189.4,84.8"/>
</Grid>
</Window>
改变
和我的viewmodel:
public class Model
{
public String Name { get; set; }
public Int32 Length { get; set; }
public BitmapSource Image { get; set; }
}
public enum TestTemplate
{
Icon,
List
}
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class RelayCommand : ICommand
{
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
}
public class ViewModel : ViewModelBase
{
#region FIELDS
#endregion
#region PROPERTIES
private TestTemplate template;
public TestTemplate TTemplate
{
get
{
return this.template;
}
set
{
this.template = value;
this.NotifyPropertyChanged("TTemplate");
}
}
public ICommand ChangeView { get; set; }
public ObservableCollection<Model> Items
{
get
{
return this.items;
}
set
{
this.items = value;
this.NotifyPropertyChanged("Items");
}
}
private ObservableCollection<Model> items;
#endregion
#region CONSTRUCTORS
/// <summary>
/// Creates a new ViewModel instance
/// </summary>
public ViewModel()
{
this.TTemplate = TestTemplate.Icon;
this.ChangeView = new RelayCommand((param) => this.ChangeViewAction(param));
this.Items = new ObservableCollection<Model>();
this.Items.Add(new Model()
{
Name = "test",
Length = 1
});
this.Items.Add(new Model()
{
Name = "test2",
Length = 2
});
}
#endregion
#region METHODS
private void ChangeViewAction(Object param)
{
if (this.TTemplate == TestTemplate.Icon)
{
this.TTemplate = TestTemplate.List;
}
else
{
this.TTemplate = TestTemplate.Icon;
}
}
#endregion
}
公共类模型
{
公共字符串名称{get;set;}
公共Int32长度{get;set;}
公共位图源图像{get;set;}
}
公共枚举测试模板
{
偶像
列表
}
公共类ViewModelBase:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
受保护的void NotifyPropertyChanged(字符串propertyName)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
}
公共类中继命令:ICommand
{
公共中继命令(操作执行)
:此(执行,空)
{
}
公共RelayCommand(操作执行,谓词canExecute)
{
if(execute==null)
抛出新的ArgumentNullException(“执行”);
_执行=执行;
_canExecute=canExecute;
}
公共布尔CanExecute(对象参数)
{
返回_canExecute==null?true:_canExecute(参数);
}
公共事件事件处理程序CanExecuteChanged
{
添加{CommandManager.RequerySuggested+=value;}
删除{CommandManager.RequerySuggested-=value;}
}
public void Execute(对象参数)
{
_执行(参数);
}
私有只读操作\u执行;
私有只读谓词_canExecute;
}
公共类ViewModel:ViewModelBase
{
#区域字段
#端区
#区域属性
私有测试模板;
公共测试模板TTemplate
{
得到
{
返回此.template;
}
设置
{
this.template=值;
本条。NotifyPropertyChanged(“TTemplate”);
}
}
公共ICommand ChangeView{get;set;}
公共可观测收集项目
{
得到
{
归还此物品;
}
设置
{
这个项目=价值;
本协议。NotifyPropertyChanged(“项目”);
}
}
私人可观测收集项目;
#端区
#区域构造函数
///
///创建新的ViewModel实例
///
公共视图模型()
{
this.TTemplate=TestTemplate.Icon;
this.ChangeView=newrelaycommand((param)=>this.ChangeViewAction(param));
this.Items=新的ObservableCollection();
this.Items.Add(新模型()
{
Name=“test”,
长度=1
});
this.Items.Add(新模型()
{
Name=“test2”,
长度=2
});
}
#端区
#区域方法
私有void ChangeViewAction(对象参数)
{
if(this.TTemplate==TestTemplate.Icon)
{
this.TTemplate=TestTemplate.List;
}
其他的
{
this.TTemplate=TestTemplate.Icon;
}
}
#端区
}
正如您在代码中看到的,我正在为ListView创建视图。一个带有图标和文本,另一个带有一些细节(尚未完成)
你能帮我吗
谢谢您可以将ElementBinding与Window DataContext一起使用。已将窗口名创建为win,并尝试将其绑定到DataContext。项到DataTemplate内列表框的ItemsSource,请参阅下面的代码
<Window x:Class="Icon_Learning.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Icon_Learning" x:Name="win"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Window.Resources>
<!-- Icon template style -->
<DataTemplate x:Key="iconTemplate" >
<ListBox ItemsSource="{Binding ElementName=win,Path=DataContext.Items}" Background="AliceBlue">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Model}">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Rectangle Height="32" Width="32" Fill="Blue"/>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
<!-- Detailed list style-->
<DataTemplate x:Key="listTemplate">
<ListBox ItemsSource="{Binding ElementName=win,Path=DataContext.Items}" Background="AliceBlue">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type local:Model}">
<DockPanel>
<TextBlock DockPanel.Dock="Bottom" Text="{Binding Name}"/>
<Rectangle Height="32" Width="32" Fill="Red"/>
</DockPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
<Style x:Key="selectableContentStyle" TargetType="{x:Type ContentControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=TTemplate}" Value="Icon">
<Setter Property="ContentTemplate" Value="{StaticResource iconTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=TTemplate}" Value="List">
<Setter Property="ContentTemplate" Value="{StaticResource listTemplate}" />
</DataTrigger>
<!-- Other listview styles -->
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<StackPanel>
<Button Command="{Binding ChangeView}">Change</Button>
</StackPanel>
<ContentControl Style="{StaticResource selectableContentStyle}" Margin="112,66,189.4,84.8"/>
</Grid>
改变
当您为
ContentControl
设置ContentTemplate
时,您就开始吃东西,但它没有内容可显示。最简单的解决方案是将当前的DataContext
绑定到Content
同时发布您的ViewModel..哦,我忘了。。。在那里,我编辑了我的帖子。您的输出窗口中是否收到任何绑定错误?结果如何显示在UI中?没有在我的输出窗口中显示任何内容,并且调试时没有结果。