zoukankan      html  css  js  c++  java
  • Prism技巧

    Prism 8.0

    xmlns:prism="http://prismlibrary.com/"  
    xmlns:cvt="clr-namespace:Module.Project1.Common.Converter" 
    
    <UserControl.Resources>
        <cvt:TypeConv x:Key="TypeConverter"/>
    </UserControl.Resources>
    
    <ContentControl prism:RegionManager.RegionName="{x:Static base:RegionNames.SyncDataRecordRegion}"
                    HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch"/>      
    

    View事件 ViewModel响应

    UserControl

    using Microsoft.Xaml.Behaviors.Wpf;
    xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
    
    <b:Interaction.Triggers>
            <b:EventTrigger EventName="Loaded">
                <b:InvokeCommandAction Command="{Binding LoadedCommand}"/>
            </b:EventTrigger>
    </b:Interaction.Triggers>
    
    
    /// <summary>
    /// 当前属性集合实体对象
    /// </summary>
    public DtoEntity PropSetEntity { get; set; }
    

    public DelegateCommand LoadedCommand { get; private set; }
    LoadedCommand = new DelegateCommand(UserControl_Loaded);

    public DelegateCommand LoadedCommand => new DelegateCommand(UserControl_Loaded);

    ChildDialog

    // father view
    <DataGridTemplateColumn Header="内容" >
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <Button Content="详情" Foreground="Blue"
                            Command="{Binding DataContext.DetailInfoCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}}" 
                            CommandParameter="{Binding ElementName=ucChildDlg}"/>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
    <base:DialogForm x:Name="ucChildDlg"/>
    
    // father viewmodel
    using Prism.Services.Dialogs;
    
    public DelegateCommand<object> GetDataCommand { get; private set; }
    DetailInfoCommand = new DelegateCommand<object>(DetailInfo_Click);
    
    private void DetailInfo_Click(object obj)
    {
        if (obj is DialogForm childDlg && PropSetEntity.SelectedItem is DemoDto dto)
        {
            var parameters = new DialogParameters
            {
                { "dto", dto}
            };
            childDlg.Show(new DemoDetailInfo(), parameters, () => { });
            childDlg.FormMargin = new Thickness(20, 20, 20, 20);
        }
    }
    
    // child viewmodel
    public class DemoDetailInfoViewModel : BindableBase, IDemoDialogAware
    {
        public void OnDialogOpened(IDialogParameters parameters)
        {
            var dto = parameters.GetValue<DemoDto>("dto");
        }
    }
    
    

    DataGrid

    <DataGrid Grid.Row="0" x:Name="DataGrid1" ItemsSource="{Binding ItemsSourceData}" SelectedItem="{Binding SelectedItem}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="SelectionChanged">
                <b:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
                                       CommandParameter="{Binding SelectedItem, ElementName=DataGrid1}"/>
            </b:EventTrigger>
            <b:EventTrigger EventName="BeginningEdit">
                <b:InvokeCommandAction Command="{Binding DataGridBeginningEditCommand}"
                           PassEventArgsToCommand="True"/>
            </b:EventTrigger>
            <b:EventTrigger EventName="CellEditEnding">
                <b:InvokeCommandAction Command="{Binding DataGridCellEditEndingCommand}"
                           PassEventArgsToCommand="True"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
        <DataGrid.Columns>
            <DataGridTextColumn Width="*" Header="列头提示2" Binding="{Binding PropertyName1}" IsReadOnly="True"/>
            <DataGridComboBoxColumn Width="*" Header="列头提示1" SelectedValueBinding="{Binding PropertyName2}"
                                               SelectedValuePath="Key" DisplayMemberPath="Value">
                <DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding DataContext.PropertyName2Source, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
                        <Setter Property="SelectedValue" Value="{Binding Key, Converter={StaticResource propertyName2Converter}}"/>
                    </Style>
                </DataGridComboBoxColumn.ElementStyle>
                <DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="ComboBox">
                        <Setter Property="ItemsSource" Value="{Binding DataContext.PropertyName2Source, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
                        <Setter Property="SelectedValue" Value="{Binding Value}"/>
                    </Style>
                </DataGridComboBoxColumn.EditingElementStyle>
            </DataGridComboBoxColumn>
            <DataGridTemplateColumn Header="操作" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                     <DataTemplate>
                         <Button Content="DetailInfo" Command="{Binding DataContext.DetailInfoCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}}" CommandParameter="{Binding ElementName=ucChildDlg}"/>
                     </DataTemplate>
                 </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>
    <base:DialogForm x:Name="ucChildDlg"/>
    

    PUBLIC ObservableCollection<DataGridRowDto> ItemsSourceData { get; private set; }
    private object _selectedItem;
    public object SelectedItem
    {
    get { return _selectedItem; }
    set { SetProperty(ref _selectedItem, value); }
    }
    ItemsSourceData通过Clear、AddRange等操作更新UI数据;
    注意:绑定的是公共属性;

    using System.Windows.Controls;
    
    public DelegateCommand<object> SelectionChangedCommand { get; private set; }
    public DelegateCommand<object> DataGridBeginningEditCommand { get; private set; }
    public DelegateCommand<object> DataGridCellEditEndingCommand { get; private set; }
    public DelegateCommand<object> DetailInfoCommand { get; private set; }
    
    SelectionChangedCommand = new DelegateCommand<object>(DataGrid_SelectionChanged);
    DataGridBeginningEditCommand = new DelegateCommand<object>(DataGrid_BeginningEdit);
    DataGridCellEditEndingCommand = new DelegateCommand<object>(DataGridCell_EditEnding);
    DetailInfoCommand = new DelegateCommand<object>(DetailInfo_Click);
    
    private void DetailInfo_Click(object obj)
    {
        if (obj is DialogForm childDlg && SelectedItem is DataGridRowDto dto)
        {
            var parameters = new DialogParameters();
            parameters.Add("dto", dto);
            childDlg.Show(new ChildView(), parameters, () => { });
            childDlg.FormMargin = new System.Windows.Thickness(200, 100, 200, 100);
        }
    }
    
    private void DataGrid_SelectionChanged(object parameter)
    {
      if(parameter != null){}
    }
    
    
    private string _preValue = string.Empty;
    private void DataGrid_BeginningEdit(object parameter)
    {
        if (parameter is DataGridBeginningEditEventArgs e)
        {
            if (e.Column.Header.Equals("列头提示1"))
            {
                _preValue = (e.Column.GetCellContent(e.Row) as ComboBox).SelectedValue.ToString();
            }
        }
    }
    
    private void DataGridCell_EditEnding(object parameter)
    {
        if (parameter is DataGridCellEditEndingEventArgs e)
        {
            string newValue = string.Empty;
            if (e.Column.Header.Equals("列头提示1"))
            {
                newValue = (e.EditingElement as ComboBox).SelectedValue.ToString();
                if (_preValue != newValue
                    && int.TryParse(newValue, out int type)
                    && e.Row.DataContext is ExampleEto item)
                {
                    // TODO
                }
            }
        }
    }
    

    其中,CommandParameter的优先级高于PassEventArgsToCommand,若两者同时出现,传递的参数是CommandParameter的值。

    ComboBox

    <ComboBox x:Name="ComboBox1" SelectedValuePath="Key" DisplayMemberPath="Value"
              ItemsSource="{Binding DtoSource}" SelectedItem="{Binding SelectedDto}"
              SelectedValue="{Binding DtoSelectedValue}" SelectedIndex="{Binding DtoIndex}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="SelectionChanged">
                <b:InvokeCommandAction Command="{Binding ComboBoxDtoSelectionChangedCommand}" PassEventArgsToCommand="True" />
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </ComboBox>
    

    using Prism.Mvvm;
    private string _dtoSelectedValue;
    public string DtoSelectedValue
    {
    get => _dtoSelectedValue;
    set => SetProperty(ref _dtoSelectedValue, value);
    }

    public DelegateCommand ComboBoxDtoSelectionChangedCommand { get; private set; }
    ComboBoxDtoSelectionChangedCommand = new DelegateCommand<object>(ComboBoxDto_SelectionChanged);
    
    private void ComboBoxDto_SelectionChanged(object parameter)
    {
       if (parameter is SelectionChangedEventArgs e && e.OriginalSource is ComboBox cmb) { }
    }
    
    

    CheckBox

    <CheckBox x:Name="CheckBox1" Tag="{x:Static comm:ParaControlType.XXX}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="Checked">
                <b:InvokeCommandAction Command="{Binding CheckBoxItemCheckedCommand}" PassEventArgsToCommand="True"/>
            </b:EventTrigger>
            <b:EventTrigger EventName="Unchecked">
                <b:InvokeCommandAction Command="{Binding CheckBoxItemUncheckedCommand}" CommandParameter="{Binding ElementName=CheckBox1}"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </CheckBox>
    
    <CheckBox  x:Name="chk_XXX" IsChecked="{Binding XXX, Converter={StaticResource StringToBoolConverter}}" Tag="XXX"
               IsEnabled="{Binding EditingItem.XXXIsEnable}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="Checked">
                <b:InvokeCommandAction Command="{Binding CheckBoxValueCheckedCommand}" PassEventArgsToCommand="True"/>
            </b:EventTrigger>
            <b:EventTrigger EventName="Unchecked">
                <b:InvokeCommandAction Command="{Binding CheckBoxValueUncheckedCommand}" PassEventArgsToCommand="True"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </CheckBox>
    
    public DelegateCommand<object> CheckBoxValueCheckedCommand { get; private set; }
    CheckBoxValueCheckedCommand = new DelegateCommand<object>(CheckBoxValue_Checked);
    private void CheckBoxValue_Checked(object parameter)
    {
        if (parameter is RoutedEventArgs e && e.OriginalSource is CheckBox ckb) { }
    }
    

    ListBox + CheckBox

    <ListBox Grid.Row="5" x:Name="ListBox1" Margin="2" ItemsSource="{Binding ListBox1Source}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <CheckBox Content="{Binding PropertyName}" IsChecked="{Binding IsCheck}" x:Name="CheckBox2">
                    <b:Interaction.Triggers>
                        <b:EventTrigger EventName="Checked">
                            <b:InvokeCommandAction Command="{Binding DataContext.ListBox1CheckedCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" 
                                                   PassEventArgsToCommand="True"/>
                        </b:EventTrigger>
                        <b:EventTrigger EventName="Unchecked">
                            <b:InvokeCommandAction Command="{Binding DataContext.ListBox1UncheckedCommand, RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=UserControl}}" 
                                                   CommandParameter="{Binding ElementName=CheckBox2}"/>
                        </b:EventTrigger>
                    </b:Interaction.Triggers>
                </CheckBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    TextBox

    <TextBox x:Name="TextBox1" Text="{Binding EditingItem.XXX}" Tag="XXX" IsEnabled="{Binding EditingItem.XXXIsEnable}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="TextChanged">
                <b:InvokeCommandAction Command="{Binding TextBox1TextChangedCommand}"/>
            </b:EventTrigger>
            <b:EventTrigger EventName="KeyDown">
                <b:InvokeCommandAction Command="{Binding TextBox1KeyDownCommand}" PassEventArgsToCommand="True"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </TextBox>
    
    private void TextBox1_KeyDown(object parameter)
    {
        if (parameter is KeyEventArgs e && e.Key == System.Windows.Input.Key.Enter && e.OriginalSource is TextBox txt)
        {
            // TODO
        }
    }
    

    RadioCheck

    可参考WPF 属性值绑定、转换

    Button

    <Button Content="测试" x:Name="ButtonTest" Command="{Binding ButtonTestCommand}" CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}" />
    

    DelegateCommand<Button> ButtonQueryCommand;
    ButtonQueryCommand = new DelegateCommand<Button>(Test_Click);

    TreeView

    <TreeView Name="TreeView1" ItemTemplate="{DynamicResource ItemNode}"
              ScrollViewer.HorizontalScrollBarVisibility="Auto"
              VirtualizingPanel.IsVirtualizing="True"
              VirtualizingStackPanel.VirtualizationMode ="Standard">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="SelectedItemChanged">
                <b:InvokeCommandAction Command="{Binding TreeView1SelectedItemChangedCommand}"
                                       CommandParameter="{Binding RelativeSource={x:Static RelativeSource.Self}}"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </TreeView>
    

    PagerSimple

    xmlns:ws="https://wessoncontrol.com/WessonControl"
    
    <ws:PagerSimple HorizontalAlignment="Center" PageSize="{Binding SelectedItem.PagerSize, Mode=TwoWay}"
                      CurrentPageCount="{Binding SelectedItem.CurrentPageCount, Mode=TwoWay}"
                      IsPagerInitialized="{Binding SelectedItem.IsPagerInitialized, Mode=TwoWay}">
        <b:Interaction.Triggers>
            <b:EventTrigger EventName="PageChangedEvent">
                <b:InvokeCommandAction Command="{Binding GetDataCommand}" PassEventArgsToCommand="True"/>
            </b:EventTrigger>
        </b:Interaction.Triggers>
    </ws:PagerSimple>
    
    // 1
    public DelegateCommand<object> GetDataCommand { get; private set; }
    // 2
    GetDataCommand = new DelegateCommand<object>(GetData_Click);
    // 3
    private void GetData_Click(object parameter)
    {
        if (parameter is PagerSimpleEventArgs e)
        {
            LocalParking.TryApiMethod(() => DataBindAsync(e.PageIndex, e.PageSize));
        }
    }
    

    RaiseCanExecuteChanged

    using System.Reflection;
    private void RaiseCanExecuteChangedAll()
    {
        var props = new List<PropertyInfo>(this.GetType().GetProperties());
        foreach (PropertyInfo prop in props)
        {
            if (prop.PropertyType.IsSubclassOf(typeof(DelegateCommandBase)))
            {
                var cmd = (DelegateCommandBase)prop.GetValue(this, null);
                cmd.RaiseCanExecuteChanged();
            }
        }
    }
    

    ViewModel找到View控件

    var region = _regionManager.Regions[RegionNames.RegionName1];
    if (region != null && region.Views.FirstOrDefault() is Views.View1 view)
    {
        _dataGrid1 = view.DataGrid1;     
    }
    

    Prism + Dialog

    public static void PrismShowInfo(string message)
    {
        var cts = new CancellationTokenSource(5000);
        cts.Token.Register(() =>
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                EventAggregator.GetEvent<LoadingFinishedEvent>().Publish();
            });
        });
        Task.Run(() =>
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                var parameters = new DialogParameters($"title=提示:&message={message}&canOperate=Collapsed")
                {
                    { "cts", cts }
                };
                DialogService.ShowDialog("MessageDialog", parameters, null);
            });
        }, cts.Token);
    }
    
    public static void PrismShowConfirm(string message, Action<IDialogResult> callback = null)
    {
        var cts = new CancellationTokenSource(5000);
        cts.Token.Register(() =>
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                EventAggregator.GetEvent<LoadingFinishedEvent>().Publish();
            });
        });
        Task.Run(() =>
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                var parameters = new DialogParameters($"title=提示:&message={message}&canOperate=Visible")
                {
                    { "cts", cts }
                };
                DialogService.ShowDialog("MessageDialog", parameters, callback);
            });
        }, cts.Token);
    }
    

    注意事项

    ViewModel可使用事件控制View界面元素

    比如TreeView控件置顶,ViewModel定义委托事件,View中操作控件;

    // ViewModel
    public event EventHandler ScrollToTopEvent;
    ScrollToTopEvent?.Invoke(this, EventArgs.Empty);
    
    public XXView()
    {
        InitializeComponent();
        if (this.DataContext is XXViewModel vm)
        {
            vm.ScrollToTopEvent += Vm_ScrollToTopEvent;
        }
    }
    private void Vm_ScrollToTopEvent(object sender, System.EventArgs e)
    {
        WSCommFunc.TreeViewScrollToTop(TreeView1);
    }
    

    ViewModel内最好不要与用户交互

    比如选择文件,可以在View中实现,在ViewModel中同步;

    // View
    <Button Content="选择" x:Name="ButtonSelectFile" Command="{Binding SelectFileCommand}" Click="ButtonSelectFile_Click" />
    private void ButtonSelectFile_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        // System.Windows.Forms.OpenFileDialog openfile 选择文件
        var btn = (Button)sender;
        btn.CommandParameter = new FileInfo(openfile.FileName);
    }
    // ViewModel
    private void SelectFile_Click(object parameter)
    {
        if (parameter is FileInfo fi)
        {
            var fileName = fi.Name;
            var filePath = fi.FullName;
        }
    }
    
  • 相关阅读:
    ETF上线技术要素
    oracle修改用户的schema
    list
    交易系统分类OMS/EMS
    类的大小2
    webpack5教程
    vue配置stylelint教程
    提高国内访问 GitHub 的速度的 9 种方案
    git常见的操作
    img 图像底部留白的原因以及解决方法
  • 原文地址:https://www.cnblogs.com/wesson2019-blog/p/14874469.html
Copyright © 2011-2022 走看看