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

WPF display content based on treeview selected item

我能够从树视图中检索到选定的项目值。现在我想根据该值更改 ScrollViewer 控件中的内容。我正在尝试显示包含容器的设施对象的 属性 值,容器包含坦克。

我是编程新手,如果我的解释不够清楚,请见谅。 谢谢。

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
}

我认为您想要做的是在 UserControl 中显示信息,该 UserControl 将包含一个带有不同控件(如文本块和文本框)的网格。 因此,您将创建一个名为 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);     
}

抱歉,我不习惯这种编写代码的错误缩进。

编辑 2:

好的,您有 2 个选择,首先您可以创建一个将实现 INotifyPropertyChanged 的​​ 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 个电流所以

当前设施虚拟机

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);     
}

您可以根据类型动态加载数据模板。请参考以下内容。您可以通过将 SelectedItem 的实例更改为不同的 class.

来切换模板
 <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; }
    }
}