动态加载与WPF内容 [英] Dynamically Load Content with WPF

查看:181
本文介绍了动态加载与WPF内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我有我创建了两个数据模板的容器。基本上一个模板将显示5与文本框和对象数据绑定到这些和其他的模板会显示一个按钮来添加特定对象。我子类DataTemplateSelector和它的作品,但是当我通过我的记录浏览选择永远不会被再次调用。

Ok I have a container that I have created two data templates for. Basically one template will show 5 textboxes with and objects data bound to them and the other template will show a button to add that particular object. I subclassed DataTemplateSelector and it works, but when I navigate through my records the Selector never gets called again.

因此,如何将我的容器重新选择它的模板。该容器是一个StackPanel中,我已经尝试过UpdateVisuals,InvalidateVisuals,InvalidateArrange和ApplyTemplate,都。

So how would I for the container to reselect it's template. The container is a StackPanel and I have already tried UpdateVisuals, InvalidateVisuals, InvalidateArrange, and ApplyTemplate.

XAML代码

<DataTemplate x:Key="advisorTemplate">
        <StackPanel Orientation="Vertical" Margin="2,2,2,2" HorizontalAlignment="Stretch" VerticalAlignment="Top">
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtAcadAdv" Watermark="Acad Adv" Width="125" Margin="2" Text="{Binding Path=Adv.AcadAdv}"/>
                <extToolkit:WatermarkTextBox Name="txtProgAdv" Watermark="Prog Adv" Width="125" Margin="2" Text="{Binding Path=Adv.ProgAdv}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtPortAdv" Watermark="Port Adv" Width="125" Margin="2" Text="{Binding Path=Adv.PortAdv}"/>
                <extToolkit:WatermarkTextBox Name="txtEleTws" Watermark="Ele Tws" Width="125" Margin="2" Text="{Binding Path=Adv.EleTws}"/>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="2,2,2,2" HorizontalAlignment="Center">
                <extToolkit:WatermarkTextBox Name="txtMatTws" Watermark="Mat Tws" Width="125" Margin="2" Text="{Binding Path=Adv.MatTws}"/>
            </StackPanel>
        </StackPanel>
    </DataTemplate>
    <DataTemplate x:Key="addAdvisor">
        <Button HorizontalAlignment="Center" VerticalAlignment="Center" Margin="2" Name="btnAddAdvisor" Click="ButtonClick" Content="Add Advisor"/>
    </DataTemplate> 



变更对本集团箱

Initialization of the Content Changed on the Group Box

grpAdv.ContentTemplateSelector = _advisorSelector;

和最后的选择代码

private readonly StudentWin _win;

    public  AdvisorDataTemplateSelector(StudentWin win)
    {
        _win = win;
    }

    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        var sp = item as StackPanel;
        var adv = sp.DataContext as Advisor;


        if (adv == null)
            return _win.FindResource("addAdvisor") as DataTemplate;

        return _win.FindResource("advisorTemplate") as DataTemplate;
    }

和这里是我的导航代码

case "btnNext":
                    {
                        if(_view.CurrentPosition < _view.Count - 1)
                        {
                            CheckForUnusedReferences(_view.GetItemAt(_view.CurrentPosition) as Student);
                            _view.MoveCurrentToNext();
                            CheckForNullReferences(_view.CurrentPosition);
                            grpAdv.ApplyTemplate();
                        }
                    }



这两个附加的方法是检查是否有关系空的学生,他们将创造它,并把它添加到数据上下文对我来说否则实体框架不会保存更改。该数据模板上面基本上都会帮我带不具有studentId当我尝试创建一个新的学生的问题。

The two additional Methods are to check if a relationship is null on the student and they will create it and add it to the data context for me or else Entity Framework won't save the changes. The data templates above will basically help me with a problem of not having the studentId when I try to create a new student.

推荐答案

从的ObservableCollection我用下面的方法来强制DataTemplateSelector重新申请。

I've used the following method to force re-application of a DataTemplateSelector.

导出并添加引发NotifyCollectionChangedEventArgs与NotifyCollectionChangedAction.Reset的方法。

Derive from ObservableCollection and add a method that raises NotifyCollectionChangedEventArgs with NotifyCollectionChangedAction.Reset.

public class MyThingCollection : ObservableCollection<MyThing>
{
    public void RaiseResetCollection()
    {
        OnCollectionChanged(new 
            NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
    }
}

您的视图模型显示此类型和实例的。ItemsControl的结合到

Your view model exposes an instance of this type and your ItemsControl binds to that.

public class MyViewModel : ... (view model base)
{
    public MyThingCollection Items{get; private set;}
}

<ItemsControl
     ItemsSource="{Binding Items}"
     ItemsTemplateSelector="{StaticResource MyTemplateSelector}"
     ...

当你需要你的DataTemplateSelector的集合重新应用调用RaiseResetCollection。

When you need your DataTemplateSelector to be re-applied call RaiseResetCollection on the collection.

我一般使用DataTemplateSelector这样

I generally use DataTemplateSelector like this

public class MyTemplateSelector : DataTemplateSelector
{
    public DataTemplate Template1 { get; set; }
    public DataTemplate Template2 { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        ... return Template1 or Template2 depending on item
    }
    ...
}

<DataTemplate x:Key="MyTemplate1" DataType="{x:Type MyType1}">
    ...
</DateTemplate>

<DataTemplate x:Key="MyTemplate2" DataType="{x:Type MyType2}">
    ...
</DateTemplate>

<local:MyTemplateSelector 
    x:Key="MyTemplateSelector" 
    Template1="{StaticResource MyTemplate1}"
    Template2="{StaticResource MyTemplate2}"
/>

这篇关于动态加载与WPF内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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