无法从内部访问Listvew.Resources视图模型的属性 [英] Unable to access viewmodel properties from inside Listvew.Resources

查看:133
本文介绍了无法从内部访问Listvew.Resources视图模型的属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想给的SelectedItem到View绑定。但是观点并不能够访问视图模型时,它是资源块内。
当在DataContext被重新分配给孩子,为的TextBlocks而不是用户控件(NoteView)

绑定工程

我缺少任何绑定?



PFB修订(全部)代码和行内注释

 <用户控件X:类=Konduva.View.NoteSearchView
< - 其他命名空间在这里 - >!
的xmlns:MC =http://schemas.openxmlformats.org/markup-compatibility/2006
MC:可忽略=D
的DataContext ={结合NoteSearch源= {静态资源定位器}}>
<网格和GT;
< ListView控件的ItemsSource ={结合票据}
的SelectedItem ={结合SelectedNote}>
< ListView.Resources>
<数据类型的DataTemplate ={X:类型VM:NoteViewModel}>
<&DockPanel中GT;
< TextBlock的文本={结合标题}/>
<弹出放置=右
PlacementTarget ={绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType =的ListViewItem}
ISOPEN ={绑定(ListViewItem.IsSelected)的RelativeSource = {的RelativeSource FindAncestor,AncestorType =的ListViewItem}
的DataContext ={绑定路径= DataContext的,的RelativeSource = {的RelativeSource AncestorType = {X:类型的ListView}}}>
<&StackPanel的GT;
<! - 这是工作 - > < TextBlock的文本={结合SelectedNote.Title}/>
<! - 这是行不通的 - > <五:NoteView的DataContext ={结合SelectedNote}/>
< / StackPanel的>
< /弹出>
< / DockPanel中>
< / DataTemplate中>
< /ListView.Resources>
< /&的ListView GT;
< /网格和GT;
< /用户控件>



NoteView:

 <网格和GT; 
< TextBlock的文本={结合标题}/> //这个文本不显示
< /网格和GT;


解决方案

更新3
由于您使用MvvmLight:在NoteView,请尝试更改

 的DataContext ={绑定注意,源= {静态资源定位器}}

 < UserControl.Style> 
<风格的TargetType =用户控件>
< setter属性=DataContext的VALUE ={绑定注意,源= {StaticResource的定位}}/>
< /样式和GT;
< /UserControl.Style>



更新2



遇到了类似的问题在几分钟前,我没有完全理解,所以我会在同一个解决方案扔在这里,看它是否有帮助。如果改成这样什么happends

 <五:?NoteView的DataContext ={绑定的RelativeSource = {的RelativeSource AncestorType = { X:弹出式}} 
路径= DataContext.SelectedNote}/>



更新



我无法重现此。尝试在NoteView构造函数中添加此。你到达DataContextChangedHandler当您更改在ListView选择?



 公共NoteView()
{
的InitializeComponent();
DependencyPropertyDescriptor DPD =
DependencyPropertyDescriptor.FromProperty(UserControl.DataContextProperty,
typeof运算(用户控件));
如果(DPD!= NULL)
{
dpd.AddValueChanged(这一点,新的EventHandler(DataContextChangedHandler));
}
}
无效DataContextChangedHandler(对象发件人,EventArgs五)
{
MessageBox.Show(DataContext的更改:+的DataContext);
}



第一个答案



您DockPanel中会得到NoteViewModel作为一个DataContext,而不是ListView和,因为这是DataContext的所有童车继承每个孩子将结束与一个NoteViewModel作为DataContext的。要使用ListView控件作为你能做到这一点弹出一个DataContext。我不知道是什么的DataContext绑定了的StackPanel做的,所以我可能会失去了一些东西。



 < DataTemplate中数据类型={X:类型VM:NoteViewModel}> 
<&DockPanel中GT;
< TextBlock的文本={结合标题}/>
<弹出放置=右
PlacementTarget ={绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType =的ListViewItem}
ISOPEN ={绑定(ListViewItem.IsSelected)的RelativeSource = {的RelativeSource FindAncestor,AncestorType =的ListViewItem}
的DataContext ={绑定路径= DataContext的,的RelativeSource = {的RelativeSource AncestorType = {X:类型的ListView}}}>
<&StackPanel的GT;
< TextBlock的文本={结合SelectedNote.Title}/>
<&StackPanel的GT;
<五:NoteView的DataContext ={结合SelectedNote}/>
< / StackPanel的>
< / StackPanel的>
< /弹出>
< / DockPanel中>
< / DataTemplate中>


I'm trying to bind the SelectedItem to a View. But the view is not able to access the viewmodel when it is inside the Resources block. When the datacontext is re-assigned to the children, the binding works for textblocks but not for UserControl (NoteView)

Am I missing any Binding?

PFB revised(entire) code and inline comments.

<UserControl x:Class="Konduva.View.NoteSearchView"
<!-- other namespaces here -->
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
DataContext="{Binding NoteSearch, Source={StaticResource Locator}}">
    <Grid>
    <ListView ItemsSource="{Binding Notes}"               
        SelectedItem="{Binding SelectedNote}">
        <ListView.Resources>
        <DataTemplate DataType="{x:Type vm:NoteViewModel}">
                    <DockPanel>
                        <TextBlock Text="{Binding Title}" />
                        <Popup Placement="Right"
                           PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"
                           IsOpen="{Binding (ListViewItem.IsSelected), RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"
                           DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}">
                            <StackPanel>
  <!-- This is working -->      <TextBlock Text="{Binding SelectedNote.Title}" />
  <!-- This is not working -->  <v:NoteView DataContext="{Binding SelectedNote}" />                                
                            </StackPanel>
                        </Popup>
                    </DockPanel>
                </DataTemplate>
            </ListView.Resources>            
        </ListView>  
    </Grid>
</UserControl>

NoteView:

<Grid>
    <TextBlock Text="{Binding Title}" /> // This Text is not displayed
</Grid>

解决方案

Update 3 Since you're using MvvmLight: in NoteView, try changing

DataContext="{Binding Note, Source={StaticResource Locator}}"

to

<UserControl.Style>
    <Style TargetType="UserControl">
        <Setter Property="DataContext" Value="{Binding Note, Source={StaticResource Locator}}"/>
    </Style>
</UserControl.Style>

Update 2

Encountered a similar problem a few minutes ago which I didn't fully understand so I'll throw in the same solution here to see if it helps. What happends if you change it to this?

<v:NoteView DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type Popup}},
                                  Path=DataContext.SelectedNote}"/>

Update

I'm unable to reproduce this. Try adding this in your NoteView constructor. Do you reach DataContextChangedHandler when you change the selection in the ListView?

public NoteView()
{
    InitializeComponent();
    DependencyPropertyDescriptor dpd = 
        DependencyPropertyDescriptor.FromProperty(UserControl.DataContextProperty, 
                                                  typeof(UserControl));
    if (dpd != null)
    {
        dpd.AddValueChanged(this, new EventHandler(DataContextChangedHandler));
    }
}
void DataContextChangedHandler(object sender, EventArgs e)
{
    MessageBox.Show("DataContext Changed: " + DataContext);
}

First answer

Your DockPanel will get the NoteViewModel as a DataContext and not the ListView and since this DataContext is inherited by all Childs every child will end up with a NoteViewModel as DataContext. To use the ListView as a DataContext for the Popup you can do this. I'm not sure what the DataContext Binding for the StackPanel does though, so I might be missing something here..

<DataTemplate DataType="{x:Type vm:NoteViewModel}">
    <DockPanel>
        <TextBlock Text="{Binding Title}" />
        <Popup Placement="Right" 
               PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}" 
               IsOpen="{Binding (ListViewItem.IsSelected), RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}"
               DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListView}}}">
            <StackPanel>
                <TextBlock Text="{Binding SelectedNote.Title}" />
                <StackPanel>
                    <v:NoteView DataContext="{Binding SelectedNote}"/>
                </StackPanel>
            </StackPanel>
        </Popup>
    </DockPanel>
</DataTemplate>

这篇关于无法从内部访问Listvew.Resources视图模型的属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆