1

考虑以下用户控件:

<UserControl ...>
    <UserControl.Resources>
        <inf:DecimalToPercentageConverter x:Key="DecimalToPercentageConverter"/>
    </UserControl.Resources>
    <Expander Margin="0,5,5,5" Style="{DynamicResource ExpanderStyle}" IsExpanded="True" IsTabStop="False">
        <Expander.Header>
            <TextBlock FontSize="15" Foreground="White" Text="{x:Static resources:Strings.GeneralOptions}"/>
        </Expander.Header>

        <ItemsControl ItemsSource="{Binding DaysViewSource}" IsTabStop="False" Name="ItemsControl">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <WrapPanel />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Border Background="White" Padding="5" BorderThickness="2">
                        <HeaderedContentControl IsTabStop="False" Width="240">
                            <HeaderedContentControl.Header>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Date, StringFormat=d}" FontSize="14" Margin="3"/>
                                    <TextBlock Text="{Binding Date, StringFormat=(ddd)}" FontSize="14" Margin="3"/>
                                </StackPanel>
                            </HeaderedContentControl.Header>
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" />
                                    <ColumnDefinition Width="*" />
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                    <RowDefinition/>
                                </Grid.RowDefinitions>

                                <StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
                                    <Image Margin="3" Width="16" Height="16" Source="{DynamicResource InformationIcon}" />
                                    <TextBlock Margin="1,3,3,3" Text="{Binding HoursPerAgentText}"/>
                                </StackPanel>

                                <TextBlock Grid.Row="1" Text="{x:Static resources:Strings.Utilization}" Margin="3" VerticalAlignment="Center"/>
                                <TextBox Grid.Row="1" Grid.Column="1" 
                                         Text="{Binding Utilization, ValidatesOnDataErrors=true, StringFormat='P2', Converter={StaticResource DecimalToPercentageConverter}}" 
                                         Margin="3" VerticalAlignment="Center" />

                                <TextBlock Grid.Row="2"  Text="{x:Static resources:Strings.Shrinkage}"  Margin="3" VerticalAlignment="Center"/>
                                <TextBox Grid.Row="2" Grid.Column="1" 
                                         Text="{Binding Shrinkage, ValidatesOnDataErrors=true, StringFormat='P2', Converter={StaticResource DecimalToPercentageConverter}}"  
                                         Margin="3" VerticalAlignment="Center"/>
                            </Grid>
                        </HeaderedContentControl>
                    </Border>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Expander>
</UserControl>

它呈现如下:

用户控件渲染

我的任务是在所有日子和两个领域实现粘贴功能。用户将从 Excel 工作表中复制值并直接粘贴到其中一个文本框中。我有解析逻辑,但我很难处理如何处理所有控件的粘贴。

到目前为止,我尝试使用带有粘贴命令的 CommandBinding 但这似乎只在后面的视图代码中给了我一个事件,理想情况下,我希望能够处理我的视图模型中的逻辑。我知道有些模式允许将命令绑定链接到具有附加属性(http://codingcontext.wordpress.com/2008/12/10/commandbindings-in-mvvm/)的视图模型,在这种情况下,我在视图模型中得到了事件,但是我得到的只是作为文本框元素的发送者(我不希望在我的视图模型中使用它)。

有没有人遇到过同样的问题或对如何优雅地解决这个问题有想法?

4

1 回答 1

0

我有一个Utility托管许多Manager类的项目,其中之一是ClipboardManager. 我的所有Manager课程都遵循该Singleton模式(意味着每个课程只能有一个)并且可以从BaseViewModel课程中获得。它们都是接口的,因此我可以为测试目的实现模拟管理器,但这是另一回事。

ClipboardManager一些标准方法,但本质上对于特定任务,我需要添加以下方法:

/// <summary>
/// Copies the SecurityPermissions object specified by the securityPermissions input parameter into the computer clipboard in the SecurityPermissions format.
/// </summary>
/// <param name="securityPermissions">The SecurityPermissions object to copy into the computer clipboard.</param>
public void SetClipboardSecurityPermissions(SecurityPermissions securityPermissions)
{
    try { SetClipboardSecurityPermissionsData(securityPermissions); }
    catch (COMException)
    {
        Thread.Sleep(0);
        try { SetClipboardSecurityPermissionsData(securityPermissions); }
        catch (COMException)
        {
            MessageBox.Show("The clipboard was inaccessible, please try again later");
        }
    }
}

private void SetClipboardSecurityPermissionsData(SecurityPermissions userSecurityPermissions)
{
    List<SecurityPermission> securityPermissions = new List<SecurityPermission>(userSecurityPermissions);
    List<SerializableSecurityPermission> serializableSecurityPermissions = new List<SerializableSecurityPermission>();
    foreach (SecurityPermission securityPermission in securityPermissions) serializableSecurityPermissions.Add(new SerializableSecurityPermission(securityPermission));
    DataObject securityPermissionsDataObject = new DataObject();
    securityPermissionsDataObject.SetData("SecurityPermissions", serializableSecurityPermissions, false);
    Clipboard.SetDataObject(securityPermissionsDataObject);
}

/// <summary>
/// Retrieves a SecurityPermissions object from the computer clipboard if any data exists in the SecurityPermissions format.
/// </summary>
public SecurityPermissions GetClipboardSecurityPermissions()
{
    if (HasClipboardGotDataFormat("SecurityPermissions"))
    {
        try { return PasteClipboardSecurityPermissions(); }
        catch (COMException)
        {
            Thread.Sleep(0);
            try { return PasteClipboardSecurityPermissions(); }
            catch (COMException)
            {
                MessageBox.Show("The clipboard was inaccessible, please try again later");
            }
        }
    }
    return new SecurityPermissions();
}

private SecurityPermissions PasteClipboardSecurityPermissions()
{
    object data = Clipboard.GetData("SecurityPermissions");
    if (data != null)
    {
        List<SecurityPermission> securityPermissions = new List<SecurityPermission>();
        List<SerializableSecurityPermission> serializableSecurityPermissions = (List<SerializableSecurityPermission>)data;
        foreach(SerializableSecurityPermission serializableSecurityPermission in serializableSecurityPermissions) securityPermissions.Add(new SecurityPermission(serializableSecurityPermission));
        return new SecurityPermissions(securityPermissions);
    }
    return new SecurityPermissions();
}

这使用标准方法之一:

/// <summary>
/// Returns true if any data currently exists in the computer clipboard in the data format specified by the dataFormat input parameter.
/// </summary>
public bool HasClipboardGotDataFormat(string dataFormat)
{
    return Clipboard.ContainsData(dataFormat);
}

公共方法是接口的方法,因此我可以从我的视图模型中访问这些方法。所以这是从视图模型处理剪贴板活动的一种方法。现在,一旦您在视图模型中获得了数据,您如何在各种控件中分配它将在很大程度上取决于您如何设置它们。

如果您有一个共同的父视图模型,那么我会在那里执行您的剪贴板活动,然后将数据分发到子控件应该很容易。

更新>>>

Button处理此问题的一种简单方法是在您的 UI中提供“粘贴” 。您可以将其连接到ICommand父视图模型中的某种...我使用自定义ActionCommand(类似于RelayCommand):

/// <summary>
/// Pastes the SecurityPermissions collection from the computer clipboard to the currently selected User.
/// </summary>
public ICommand PasteUserSecurityPermissions
{
    get { return new ActionCommand(action => ((SecurityViewModel)ViewModel).
PasteSecurityPermissions(ClipboardManager.GetClipboardSecurityPermissions()), 
canExecute => ClipboardManager.HasClipboardGotDataFormat("SecurityPermissions")); }
}

然后在子视图模型中:

/// <summary>
/// Pastes the SecurityPermissions collection from the computer clipboard to the currently selected User object.
/// </summary>
public void PasteSecurityPermissions(SecurityPermissions securityPermissions)
{
    // Do whatever you like with the pasted data here
}

在您的情况下,您可以在每个子视图模型中使用其中一种粘贴方法......既好又简单。:)

于 2013-10-04T10:25:47.743 回答