WPF 使用用戶控件UserControl來切換界面(二)


在上一篇文章中https://www.cnblogs.com/lizhiqiang0204/p/12367553.html我們使用按鍵Button來切換界面的,這次我們使用自定義的ItemsControl數據模板來切換頁面。MainWindow.xaml如下

<Window.DataContext>
        <local:MainWindowVeiwModel></local:MainWindowVeiwModel>
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Border Grid.Column ="0"  BorderThickness="3" BorderBrush="Gray" >
            <ScrollViewer Grid.Row="2">
                <ItemsControl ItemsSource="{Binding Items}">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Grid Style="{StaticResource MenuItemGrid}"> 
                                <Border MouseDown="UIElement_OnMouseDown" Style="{StaticResource MenuItem}"   Background="{Binding BackColor}"   >
                                    <TextBlock Grid.Row="0" Grid.Column="1" Style="{StaticResource H5}"  Text="{Binding Title}"/>
                                </Border>
                            </Grid>
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </ScrollViewer>
        </Border>

        <Border Grid.Column ="1" BorderBrush="Gray" BorderThickness="3" >
            <ContentPresenter  Content="{Binding Content}"/>
            <!--使用內容呈現器來顯示用戶控件界面-->
        </Border>
    </Grid>
MainWindow.xaml

MainWindow.xaml.cs如下

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var sample = (SampleVm)((Border)sender).DataContext;//Border屬於ItemsControl的其中一員,所以(Border)sender).DataContext 是MainWindowVeiwModel類成員Items數組中的其中一類(即SampleVm)
            var hvm = (MainWindowVeiwModel)DataContext;//MainWindow的數據上下文指定MainWindowVeiwModel類
            hvm.Content = (UserControl)Activator.CreateInstance(sample.Content);//主頁面MainWindow.xaml中的內容呈現器ContentPresenter指向選中Items數組中的UserControl句柄。
            hvm.Items[hvm.SelectId].BackColor = new SolidColorBrush(Colors.Transparent);//把上一次選中的背景色改成透明色
            hvm.Items[sample.Id].BackColor = new SolidColorBrush(Colors.Gray);//把這次選中的背景色改成灰色
            hvm.SelectId = sample.Id;//已選擇的ID改成本次選中的ID

        }
    }
MainWindow.xaml.cs

MainWindow的DataContext上下文類MainWindowViewModel類如下

public class MainWindowVeiwModel : INotifyPropertyChanged
    {
        private UserControl _content;
        private SampleVm[] _Items;
        public int SelectId;

        public MainWindowVeiwModel()//在構造方法中向Items注冊各個用戶控件、id以及對應的標題
        {
            _Items = new[]
            {
                new SampleVm("頁面1", typeof(UserControl1),0),
                new SampleVm("頁面2", typeof(UserControl2),1),
            };
        }
        //ItemsControl中的數據模板綁定SampleVm類數組
        public SampleVm[] Items
        {
            get { return _Items; }
            set
            {
                _Items = value;
                OnPropertyChanged("Items");
            }
        }
        //主頁面的內容呈現器
        public UserControl Content
        {
            get { return _content; }
            set
            {
                _content = value;
                OnPropertyChanged("Content");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
MainWindowVeiwModel

保存各個頁面信息的類SampleVm如下

public class SampleVm : INotifyPropertyChanged
    {
        private SolidColorBrush _BackColor;
        public SampleVm(string title, Type content, int id)
        {
            Title = title;
            Content = content;
            Id = id;
        }
        public int Id { get; private set; }
        public string Title { get; set; }
        public Type Content { get; set; }

        public SolidColorBrush BackColor 
        {
            get { return _BackColor; }
            set { _BackColor = value; OnPropertyChanged("BackColor"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
SampleVm

App資源字典如下

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:UserControl_change_interface4">
    <Style x:Key="Title" TargetType="TextBlock">
        <Setter Property="HorizontalAlignment" Value="Center"></Setter>
        <Setter Property="Foreground" Value="#303030"></Setter>
        <Setter Property="TextAlignment" Value="Center"></Setter>
        <Setter Property="TextWrapping" Value="Wrap"></Setter>
    </Style>


    <Style x:Key="H3" TargetType="TextBlock" BasedOn="{StaticResource Title}">
        <Setter Property="FontSize" Value="24"></Setter>
    </Style>
    <Style x:Key="H5" TargetType="TextBlock" >
        <Setter Property="FontSize" Value="20"></Setter>
    </Style>

    <Style x:Key="H6" TargetType="Label" >
        <Setter Property="Foreground" Value="Blue"></Setter>
        <Setter Property="FontSize" Value="30"></Setter>
    </Style>

    <Style x:Key="MenuItem" TargetType="Border">
        <!--<Setter Property="Cursor" Value="Hand"></Setter>-->
        <Setter Property="Height" Value="50"></Setter>
        <Setter Property="BorderThickness" Value="0 1 0 1"></Setter>
        <Setter Property="BorderBrush" Value="#EBEBEB"></Setter>
        <!--<Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="WhiteSmoke"></Setter>
            </Trigger>
        </Style.Triggers>-->
    </Style>

    <Style x:Key="MenuItemGrid" TargetType="Grid">
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="WhiteSmoke"></Setter>
            </Trigger>
        </Style.Triggers>
    </Style>
</ResourceDictionary>
AppDictionary.xaml

源碼下載地址 https://github.com/lizhiqiang0204/UserControl-change-interface2_1

整體效果如下

MainWindowVeiwModel類中是直接引用UserControl1和UserControl2的,如果想在MainWindow.xaml.cs中訪問修改UserControl1實體類類里面的成員,那只能訪問在實體類成員前加static修飾,前面的例程中用戶控件成員確實使用static修飾的。當然也可以在MainWindowVeiwModel類中實例化用戶控件類,每次切換頁面直接更改把主頁面的內容呈現器ContentPresenter的Content指向MainWindowVeiwModel中實例化的成員就可以改變頁面。該例程所有前台.xaml不變,所有后台.cs文件均有改變。

public partial class MainWindow : Window
    {
        public MainWindowVeiwModel MW; 
        public MainWindow()
        {
            InitializeComponent();
            MW = (MainWindowVeiwModel)DataContext;//MW就是MainWindowVeiwModel實體類
        }

        private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var sample = (SampleVm)((Border)sender).DataContext;//Border屬於ItemsControl的其中一員,所以(Border)sender).DataContext 是MainWindowVeiwModel類成員Items數組中的其中一類(即SampleVm)
            MW.Content = MW.Items[sample.Id].User;//主頁面MainWindow.xaml中的內容呈現器ContentPresenter指向選中Items數組中的UserControl句柄。
            MW.Items[MW.SelectId].BackColor = new SolidColorBrush(Colors.Transparent);//把上一次選中的背景色改成透明色
            MW.Items[sample.Id].BackColor = new SolidColorBrush(Colors.Gray);//把這次選中的背景色改成灰色
            MW.SelectId = sample.Id;//已選擇的ID改成本次選中的ID

        }

        private void btnClearCountClick(object sender, RoutedEventArgs e)
        {
            (MW.User1 as UserControl1).myStr = "0";
            (MW.User1 as UserControl1).i = 0;
            (MW.User2 as UserControl2).myStr = "0";
            (MW.User2 as UserControl2).i = 0;
        }
    }
MainWindow.xaml.cs
public class MainWindowVeiwModel : INotifyPropertyChanged
    {
        private UserControl _content;
        public SampleVm[] _Items;
        public int SelectId;
        public UserControl User1 = new UserControl1();
        public UserControl User2 = new UserControl2();

        public MainWindowVeiwModel()//在構造方法中向Items注冊各個用戶控件、id以及對應的標題
        {
            _Items = new[]
            {
                new SampleVm("頁面1", User1,0),
                new SampleVm("頁面2", User2,1),
            };
        }
        //ItemsControl中的數據模板綁定SampleVm類數組
        public SampleVm[] Items
        {
            get { return _Items; }
            set
            {
                _Items = value;
                OnPropertyChanged("Items");
            }
        }
        //主頁面的內容呈現器
        public UserControl Content
        {
            get { return _content; }
            set
            {
                _content = value;
                OnPropertyChanged("Content");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
MainWindowVeiwModel.cs
public class SampleVm : INotifyPropertyChanged
    {
        private SolidColorBrush _BackColor;
        public SampleVm(string title, Type content, int id)
        {
            Title = title;
            Content = content;
            Id = id;
        }
        public SampleVm(string title, UserControl user, int id)
        {
            Title = title;
            User = user;
            Id = id;
        }
        public int Id { get; private set; }
        public string Title { get; set; }
        public Type Content { get; set; }
        public UserControl User { get; set; }

        public SolidColorBrush BackColor 
        {
            get { return _BackColor; }
            set { _BackColor = value; OnPropertyChanged("BackColor"); }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
SampleVm.cs
public partial class UserControl1 : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public  int i = 0;

        private  string _myStr = "0";
        public  string myStr //Label 標簽內容綁定到這個myStr字符串
        {
            get { return _myStr; }
            set
            {
                _myStr = value;
                OnPropertyChanged("myStr");//異步更新屬性
            }
        }
        public UserControl1()
        {
            InitializeComponent();
            DataContext = this;//設置綁定數據的上下文為UserControl1類
        }

        //累加按鍵處理事件
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            i++;//按一下數值累加一次
            myStr = i.ToString();//把累加完后的數值轉換成字符串賦給標簽內容值(立刻更新標簽內容)
        }

    }
UserControl1.xaml.cs
public partial class UserControl2 : UserControl, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
        public  int i = 0;
        private string _myStr = "0";
        public  string myStr //Label 標簽內容綁定到這個myStr字符串
        {
            get { return _myStr; }
            set
            {
                _myStr = value;
                OnPropertyChanged("myStr");//異步更新屬性
            }
        }

        public UserControl2()
        {
            InitializeComponent();
            DataContext = this;//設置綁定數據的上下文為UserControl2類
        }
        //累加按鍵處理事件
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            i++;//按一下數值累加一次
            myStr = i.ToString();//把累加完后的數值轉換成字符串賦給標簽內容值(立刻更新標簽內容)
        }
    }
UserControl2.xaml.cs

源碼下載地址https://github.com/lizhiqiang0204/UserControl-change-interface2_2 

效果圖如下

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM