WPF基于树视图选择项显示内容

时间:2015-04-10 19:21:18

标签: c# wpf xaml mvvm treeview

我能够从我的树视图中检索所选的项目值。现在我想基于该值更改ScrollViewer控件中的内容。我正在尝试显示Facility对象的属性值,该对象包含包含Tanks的Containments。

如果我的解释不够明确,我是编程抱歉的新手。 谢谢。

MyWindow.xaml

<Window.DataContext>
    <local:VisioFacilityExportViewModel/>
</Window.DataContext>
<Window.Resources>
    <DataTemplate x:Key="FacilityTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Label Content="Facility ID:"/>
            <TextBox Grid.Row="0" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].FacilityID}"/>
            <Label Content="Address:" Grid.Row="1"/>
            <TextBox Grid.Row="1" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Address}"/>
            <Label Content="Description:" Grid.Row="2"/>
            <TextBox Grid.Row="2" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Description}"/>
            <Label Content="Layout And Drainage:" Grid.Row="3"/>
            <TextBox Grid.Row="3" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].LayoutAndDrainage}"/>
            <Label Content="Latitude:" Grid.Row="4"/>
            <TextBox Grid.Row="4" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Latitude}"/>
            <Label Content="Longitude:" Grid.Row="5"/>
            <TextBox Grid.Row="5" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Longitude}"/>
            <Label Content="City:" Grid.Row="6"/>
            <TextBox Grid.Row="6" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].City.Name}"/>
            <Label Content="County:" Grid.Row="7"/>
            <TextBox Grid.Row="7" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].County.Name}"/>
            <Label Content="Name:" Grid.Row="8"/>
            <TextBox Grid.Row="8" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Name}"/>
            <Label Content="Run:" Grid.Row="9"/>
            <TextBox Grid.Row="9" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].Run}"/>
            <Label Content="Surface Flow Direction:" Grid.Row="10"/>
            <TextBox Grid.Row="10" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].SurfaceFlowDirection}"/>
            <Label Content="API Number:" Grid.Row="11"/>
            <TextBox Grid.Row="11" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].APINumber}"/>
            <Label Content="Distance To Navigable Waters:" Grid.Row="12"/>
            <TextBox Grid.Row="12" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].DistanceToNavigableWaters}"/>
            <Label Content="Project Phase:" Grid.Row="13"/>
            <TextBox Grid.Row="13" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].APINumber}"/>
            <Label Content="Unique ID:" Grid.Row="14"/>
            <TextBox Grid.Row="14" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].UniqueID}"/>
            <Label Content="Operational Field:" Grid.Row="15"/>
            <TextBox Grid.Row="15" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].OperationalField}"/>
            <Label Content="Facility Type:" Grid.Row="16"/>
            <TextBox Grid.Row="16" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].FacilityType}"/>
            <Label Content="Project Number:" Grid.Row="17"/>
            <TextBox Grid.Row="17" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].ProjectNumber}"/>
            <Label Content="Project Phase:" Grid.Row="18"/>
            <TextBox Grid.Row="18" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].ProjectPhase}"/>
            <Label Content="Report Number:" Grid.Row="19"/>
            <TextBox Grid.Row="19" Grid.Column="1" Height="20" Text="{Binding ListFacilities[0].ReportNumber}"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="ContainmentTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Label Content="Name:"/>
            <TextBox Grid.Column="1" Height="20" Text="{Binding ListContainments[0].Name}"/>
            <Label Content="Height:" Grid.Row="1"/>
            <TextBox Grid.Row="1" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].Height}"/>
            <Label Content="Diameter:" Grid.Row="2"/>
            <TextBox Grid.Row="2" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].TankPadHeight}"/>
            <Label Content="County:" Grid.Row="3"/>
            <TextBox Grid.Row="3" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].TankPadWidth}"/>
            <Label Content="Inner Length:" Grid.Row="4"/>
            <TextBox Grid.Row="4" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].TankPadLength}"/>
            <Label Content="Inner Width:" Grid.Row="5"/>
            <TextBox Grid.Row="5" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].InnerLength}"/>
            <Label Content="Top Length:" Grid.Row="6"/>
            <TextBox Grid.Row="6" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].InnerWidth}"/>
            <Label Content="Top Width:" Grid.Row="7"/>
            <TextBox Grid.Row="7" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].TopLength}"/>
            <Label Content="Construction:" Grid.Row="8"/>
            <TextBox Grid.Row="8" Grid.Column="1" Height="20" Text="{Binding ListContainments[0].TopWidth}"/>
            <Label Content="Fill Materials:" Grid.Row="9"/>
            <TextBox Grid.Row="9" Grid.Column="1" Height="20"  Text="{Binding ListContainments[0].Construction}"/>
            <Label Content="Fill Material Height (Top):" Grid.Row="10"/>
            <TextBox Grid.Row="10" Grid.Column="1" Height="20"  Text="{Binding ListContainments[0].Diameter}"/>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="TanksTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="200"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
                <RowDefinition Height="30"/>
            </Grid.RowDefinitions>
            <Label Content="Name:"/>
            <TextBox Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Name}"/>
            <Label Content="Height:" Grid.Row="1"/>
            <TextBox Grid.Row="1" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Height}"/>
            <Label Content="Diameter:" Grid.Row="2"/>
            <TextBox Grid.Row="2" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Diameter}"/>
            <Label Content="Is in Service:" Grid.Row="3"/>
            <TextBox Grid.Row="3" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].IsInService}"/>
            <Label Content="Is on Pad:" Grid.Row="4"/>
            <CheckBox Grid.Row="4" Grid.Column="1" Height="20" IsChecked="{Binding ListTanks[0].IsOnPad}"/>
            <Label Content="Contents:" Grid.Row="5"/>
            <TextBox Grid.Row="5" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Contents}"/>
            <Label Content="Year Constructed:" Grid.Row="6"/>
            <TextBox Grid.Row="6" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].YearConstructed}"/>
            <Label Content="Material:" Grid.Row="7"/>
            <TextBox Grid.Row="7" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Material}"/>
            <Label Content="Is Portable:" Grid.Row="8"/>
            <CheckBox Grid.Row="8" Grid.Column="1" Height="20" IsChecked="{Binding ListTanks[0].IsPortable}"/>
            <Label Content="Is Isolated:" Grid.Row="9"/>
            <CheckBox Grid.Row="9" Grid.Column="1" Height="20" IsChecked="{Binding ListTanks[0].IsIsolated}"/>
            <Label Content="Quantity:" Grid.Row="10"/>
            <TextBox Grid.Row="10" Grid.Column="1" Height="20" Text="{Binding ListTanks[0].Quantity}"/>
            <Label Content="Orientation:" Grid.Row="11"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
<Grid Margin="5" Height="Auto">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <TreeView Name="trvFacility" ItemsSource="{Binding MenuItems}" VirtualizingStackPanel.IsVirtualizing="True" Padding="10" Margin="5" Width="220">
        <i:Interaction.Behaviors>
            <local:BindableSelectedItemBehavior SelectedItem="{Binding SelectedItem,Mode=TwoWay}"/>
        </i:Interaction.Behaviors>
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate ItemsSource="{Binding Children}" DataType="{x:Type entities:MenuItemCust}">
                <TextBlock Text="{Binding Name}"/>
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    <ScrollViewer Grid.Row="0" Grid.Column="1" Margin="5" VerticalScrollBarVisibility="Visible">
               DataTemplate here
    </ScrollViewer>
    <Button Content="Save" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" Width="60" Height="25" Margin="0,0,5,0"  HorizontalAlignment="Right"/>
</Grid>

MyWindowViewModel.cs

public class VisioFacilityExportViewModel : INotifyPropertyChanged
{
    public VisioFacilityExportViewModel()
    {
        _lstFacilities = new ObservableCollection<Facility>(DatabaseHandler.GetFacilities().Where(f => f.FacilityID == 2015012314001933));
        _lstContainments = _lstFacilities[0].Containment;
        _lstTanks = _lstContainments[0].Tanks;
        List<MenuItemCust> lstRoot = new List<MenuItemCust>();
        List<MenuItemCust> lstContainment = new List<MenuItemCust>();
        List<MenuItemCust> lstTanks = new List<MenuItemCust>();
        MenuItems = new List<MenuItemCust>();
        foreach (var f in _lstFacilities)
        {
            foreach (var c in f.Containment)
            {
                lstTanks.AddRange(c.Tanks.Select(t => new MenuItemCust { Name = t.Name, Info = "Tanks"}));
                lstContainment.Add(new MenuItemCust { Name = c.Name, Children = lstTanks, Info = "Containment" });
            }
            lstRoot.Add(new MenuItemCust { Name = "Containment", Children = lstContainment, Info = "Facility"});
            MenuItems.Add(new MenuItemCust { Name = "Facility", Children = lstRoot });
        }
    }

    private ObservableCollection<Tank> _lstTanks;
    public ObservableCollection<Tank> ListTanks
    {
        get { return _lstTanks; }
        set
        {
            _lstTanks = value;
            NotifyPropertyChanged("ListTanks");
        }
    }

    private ObservableCollection<Containment> _lstContainments;
    public ObservableCollection<Containment> ListContainments
    {
        get { return _lstContainments; }
        set
        {
            _lstContainments = value;
            NotifyPropertyChanged("ListContainments");
        }
    }

    private ObservableCollection<Facility> _lstFacilities;
    public ObservableCollection<Facility> ListFacilities
    {
        get { return _lstFacilities; }
        set
        {
            _lstFacilities = value;
            NotifyPropertyChanged("ListFacilities");
        }
    }
    private List<MenuItemCust> _menuItems;
    public List<MenuItemCust> MenuItems
    {
        get { return _menuItems; }
        set
        {
            _menuItems = value;
            NotifyPropertyChanged("MenuItems");
        }
    }

    private static object _selectedItem = null;
    public static object SelectedItem
    {
        get { return _selectedItem; }
        private set
        {
            if (_selectedItem != value)
            {
                _selectedItem = value;
                OnSelectedItemChanged();
            }
        }
    }

    public static void OnSelectedItemChanged()
    {
        var item = (MenuItemCust) SelectedItem;
        if (item.Name == "Facility")
        {

        }
        else if (item.Info == "Containment")
        {

        }
        else if (item.Info == "Tanks")
        {

        }
    }
    #region iNotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
    #endregion
}

2 个答案:

答案 0 :(得分:1)

我认为你想要做的是在UserControl中显示信息,其中包含一个带有不同控件的网格,如textblock和textbox。 因此,您将创建一个名为FacilityView和FacilityViewModel的新UserControl,并且FacilityView将包含一个带有Facility Ojbect属性的网格 首先,我将在MyWindowViewModel中创建一个名为

的属性
private Facility currentFacility;

public Facility CurrentFacility
{
 get{return currentFacility;}
 set{ currentFacility = value ;
 notifyPropertyChange("CurrentFacility")    
}

在您的MainWindowsView(xaml)

<DataTemplate DataType="{x:Type localAdder:FacilityViewModel}">
        <localAdder:FacilityView />
</DataTemplate>

<UserControl Grid.Row="1" Grid.Column="2" 
 Content="{Binding CurrentFacility,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True}">
</UserControl>

在你的SelectedItem中你会

if (selectedItem is Facility)
{
CurrentFacility = new FacilityViewModel(selectedItem as Facility);     
}

对于不好的缩进,我不会使用这个代码。

EDIT2:

好的,你有2个选择,首先你可以创建一个实现INotifyPropertyChanged的BaseViewModel。

FacilityViewModel:BaseViewModel

TankViewModel:BaseViewModel

ContainmentViewModel:BaseViewModel

这样您就可以将CurrentFacilityViewModel更改为CurrentBaseViewModel

private BaseViewModel currentBaseXXX;

public BaseViewModel CurrentBaseXXX
{
 get{return currentBaseXXX;}
 set{ currentBaseXXX= value ;
 notifyPropertyChange("CurrentBaseXXX")    
}

在你的SelectedItem中你会

if (selectedItem is Facility)
{
CurrentBaseXXX= new FacilityViewModel(selectedItem as Facility);     
}
if (selectedItem is Tank)
{
CurrentBaseXXX= new TankViewModel(selectedItem as Tank);     
}
if (selectedItem is Containers)
{
CurrentBaseXXX= new ContainersViewModel(selectedItem as Containers);     
}

选项2

你将有3个当前的

CurrentFacilityVM

CurrentTankVM

CurrentContainerVM

在你的SelectedItem中你会

CurrentFacilityVM = null;

CurrentTankVM =null;

CurrentContainerVM =null;
if (selectedItem is Facility)
{
CurrentFacilityVM = new FacilityViewModel(selectedItem as Facility);     
}
if (selectedItem is Tank)
{
CurrentTankVM = new TankViewModel(selectedItem as Tank);     
}
if (selectedItem is Containers)
{
CurrentContainerVM = new ContainersViewModel(selectedItem as Containers);     
}

答案 1 :(得分:0)

您可以根据类型动态加载数据模板。请参阅以下内容。您可以通过将SelectedItem的实例更改为Different类来切换模板。

 <Window.Resources>
    <DataTemplate DataType="{x:Type entities:Facility}">
        <Grid>
            <TextBlock Text="{Binding FacilityName}" />
        </Grid>
    </DataTemplate>
    <DataTemplate DataType="{x:Type entities:Containment}">
        <Grid>
            <TextBlock Text="{Binding ContainmentName}"/>
        </Grid>
    </DataTemplate>
    <DataTemplate DataType="{x:Type entities:Tank}">
        <Grid>
            <TextBlock Text="{Binding TankName}"></TextBlock>
        </Grid>
    </DataTemplate>
</Window.Resources>
<Grid Margin="5" Height="Auto">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <ScrollViewer Grid.Row="0" Grid.Column="1" Margin="5" VerticalScrollBarVisibility="Visible" DataContext="{Binding SelectedItem}">
        <ContentControl Content="{Binding }"/>
    </ScrollViewer>
    <Button Content="Save" Grid.Row="1" Grid.ColumnSpan="2" Grid.Column="0" Width="60" Height="25" Margin="0,0,5,0"  HorizontalAlignment="Right"/>
</Grid>

public partial class Download : Window
{
    public Download()
    {
        InitializeComponent();
        this.DataContext = new VisioFacilityExportViewModel();
    }
}

public class VisioFacilityExportViewModel : INotifyPropertyChanged
{
    public VisioFacilityExportViewModel()
    {
        //SelectedItem = new Facility() { FacilityName = "Facility" };
        //SelectedItem = new Tank() { TankName = "Tank" };
        SelectedItem = new Containment() { ContainmentName = "Containment" };
    }

    private  object _selectedItem = null;
    public object SelectedItem
    {
        get { return _selectedItem; }
        private set
        {
            if (_selectedItem != value)
            {
                _selectedItem = value;
                NotifyPropertyChanged("SelectedItem");
            }
        }
    }


    #region iNotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(property));
    }
    #endregion
}

public class Tank
{
    private string myVar;

    public string TankName
    {
        get { return myVar; }
        set { myVar = value; }
    }

}
class Facility
{

    private string myVar;

    public string FacilityName
    {
        get { return myVar; }
        set { myVar = value; }
    }
}
class Containment
{
    private string myVar;

    public string ContainmentName
    {
        get { return myVar; }
        set { myVar = value; }
    }
}