如何基于ListBox WPF MVVM模型中的选定项隐藏和显示用户控件

时间:2013-10-31 10:13:39

标签: c# wpf mvvm binding listbox

我的MainWindow中有3个UserControl,在我的UserControl1中,我有一个带有一些名称的ListBox。当我们启动应用程序时,UserControl2和3不可见。

当我在usercontrol1的列表框中选择一些名称时,usercontrol2应出现在我的主窗口上,当我选择其他名称时,usercontrol3应出现在我的主窗口上。请大家帮帮我,我是新来的

这是我的UserControlXaml代码

<UserControl x:Class="Wpf_MVVM.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         x:Name="uc1" Height="Auto" Width="Auto">
<Grid>
    <ListBox Name="listbox" ItemsSource="{Binding mylist}"  HorizontalAlignment="Left" Height="310" VerticalAlignment="Top" Width="150" Margin="0,40,0,0" FontSize="15">

    </ListBox>
    <Label Content="Conversations" HorizontalAlignment="Left" VerticalAlignment="Top"  Height="40" Width="150" FontSize="20" Background="SkyBlue"/>
    <Button Content="Create New Chat" Height="30" HorizontalAlignment="Left" Margin="0,350,0,0" VerticalAlignment="Top" Width="150"/>

</Grid>
</UserControl>

这是我的.cs代码

public partial class UserControl1 : UserControl
{
    User1 User1 = new User1();
    public UserControl1()
    {
        InitializeComponent();
        this.DataContext = User1;
    }
}
public class User1
{
    private ObservableCollection<string> _mylist = new ObservableCollection<string>();

    public ObservableCollection<string> mylist { get { return _mylist; } }

    public User1()
    {
        mylist.Add("Name1");
        mylist.Add("Name2");
        mylist.Add("Name3");
        mylist.Add("Name4");

    }

这是我的mainwindow.xaml代码

<Window x:Class="Wpf_MVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Wpf_MVVM" 
    Title="MainWindow" Background="SlateGray" Height="420" Width="550" >
<Window.Resources>
    <BooleanToVisibilityConverter x:Key="VisibilityConverter" />
</Window.Resources>

<Grid>

    <local:UserControl1 x:Name="uc1"   HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <StackPanel>

        <local:UserControl2 x:Name="uc2"  Visibility="{Binding SelectedItem, Converter={StaticResource VisibilityConverter}}"  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="150,29,0,0" />
        <local:UserControl3 x:Name="uc3" Visibility="{Binding SelectedItem1, Converter={StaticResource VisibilityConverter}}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="340,29,0,0"/>


    </StackPanel>



</Grid>
</Window>

这是我的usercontrol2和3

的viewmodel代码
  public class User : INotifyPropertyChanged
    {

        private bool _selectedItem;
        public bool SelectedItem
        {
            get { return _selectedItem; }
            set
            {
                _selectedItem = value;
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
            }
        }
        private bool _selectedItem1;
        public bool SelectedItem1
        {
            get { return _selectedItem1; }
            set
            {
                _selectedItem1 = value;
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem1"));
            }
        }

        public class BooleanToVisibilityConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {

                return value == null ? Visibility.Collapsed : Visibility.Visible;
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {

                return null;
            }

        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void Notify(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private readonly ObservableCollection<string> items = new ObservableCollection<string>();
        private string text;
        private readonly ObservableCollection<string> newitems = new ObservableCollection<string>();
        private string newtext;

        public class Command : ICommand
        {
            private readonly Action action;

            public Command(Action action)
            {
                this.action = action;
            }

            public bool CanExecute(object parameter)
            {
                return true;
            }


            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
                action();
            }
        }

        private readonly ICommand addCommand;
        private readonly ICommand sendCommand;
        public User()
        {

            addCommand = new Command(() => items.Add(Text));
            sendCommand = new Command(() => newitems.Add(NewText));
        }



        public IEnumerable<string> Items
        {
            get { return items; }
        }

        public IEnumerable<string> NewItems
        {
            get { return newitems; }
        }


        public ICommand AddCommand
        {
            get { return addCommand; }
        }
        public ICommand SendCommand
        {
            get { return sendCommand; }
        }

        public string Text
        {
            get { return text; }
            set
            {
                if (text == value)
                    return;

                text = value;
                Notify("Text");
            }
        }
        public string NewText
        {
            get { return newtext; }
            set
            {
                if (newtext == value)
                    return;

                newtext = value;
                Notify("NewText");
            }
        }
    }
}

2 个答案:

答案 0 :(得分:1)

如果您想使用BooleanToVisibilityConverter,则需要在视图模型中创建一些bool属性:

public bool IsControl1Visible
{
    get { return isControl1Visible; }
    set { isControl1Visible = value; NotifyPropertyChanged("IsControl1Visible"); }
}

public bool IsControl2Visible
{
    get { return isControl2Visible; }
    set { isControl2Visible = value; NotifyPropertyChanged("IsControl2Visible"); }
}

然后你需要一个SelectedItem属性:

public string SelectedItem
{
    get { return selectedItem; }
    set { selectedItem = value; NotifyPropertyChanged("SelectedItem"); }
}

您还需要在第一个SelectedItem DependencyProperty中创建UserControl并将其绑定到ListBox.SelectedItem属性(我假设您知道如何或可以找到如何创建DependencyProperty):

UserControl1

<ListBox Name="listbox" ItemsSource="{Binding mylist}" 
    SelectedItem="{Binding SelectedItem, RelativeSource={AncestorType={x:Type 
    local:UserControl1}}}" HorizontalAlignment="Left" Height="310" 
    VerticalAlignment="Top" Width="150" Margin="0,40,0,0" FontSize="15" />

然后您可以Bind UserControl1.SelectedItem属性(内部绑定到ListBox.SelectedItem属性)到您的视图模型:

<local:UserControl1 x:Name="uc1" SelectedItem="{Binding SelectedItem}" 
    HorizontalAlignment="Left" VerticalAlignment="Top"/>

最后,我们可以更新我们的视图模型SelectedItem属性,以更改其他Usercontrol的可见性:

public string SelectedItem
{
    get { return selectedItem; }
    set 
    {
        selectedItem = value;
        NotifyPropertyChanged("SelectedItem");
        if (selectedItem == "Some value") 
        {
            IsControl1Visible = true;
            IsControl2Visible = false;
        }
        else
        {
            IsControl2Visible = true;
            IsControl1Visible = false;
        }
    }
}

作为此方法的替代方法,您可能会找到我对WPF MVVM navigate views帖子有用的答案。

答案 1 :(得分:0)

您可以使用Binding的强大功能而无需额外的C#代码

<Grid>
  <local:UserControl1 x:Name="uc1"   HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <StackPanel>
      <local:UserControl2 x:Name="uc2" Visibility="{Binding ElementName=uc1, Path=SelectedItem, Converter={StaticResource VisibilityConverter}}"  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="150,29,0,0" />
      <local:UserControl3 x:Name="uc3" Visibility="{Binding ElementName=uc2, Path=SelectedItem, Converter={StaticResource VisibilityConverter}}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="340,29,0,0"/>
    </StackPanel>
</Grid>

或使用数据触发器:

<Style TargetType="{x:Type Control}" x:Key="VisibilityStyle1">
            <Setter Property="Visibility" Value="Visible" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedItem, ElementName=uc1}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Hidden" />
                </DataTrigger>
            </Style.Triggers>
</Style>

<Style TargetType="{x:Type Control}" x:Key="VisibilityStyle2">
            <Setter Property="Visibility" Value="Visible" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding SelectedItem, ElementName=uc2}" Value="{x:Null}">
                    <Setter Property="Visibility" Value="Hidden" />
                </DataTrigger>
            </Style.Triggers>
</Style>

<Grid>
  <local:UserControl1 x:Name="uc1"   HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <StackPanel>
      <local:UserControl2 x:Name="uc2" Style="{DynamicResource VisibilityStyle1}"  HorizontalAlignment="Left" VerticalAlignment="Top" Margin="150,29,0,0" />
      <local:UserControl3 x:Name="uc3" tyle="{DynamicResource VisibilityStyle2}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="340,29,0,0"/>
    </StackPanel>
</Grid>