Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从DataTemplate访问ObservableCollection_C#_Wpf - Fatal编程技术网

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中?没有在我的输出窗口中显示任何内容,并且调试时没有结果。