开发者

OpenFileDialog with WPF in M-V-VM pattern

开发者 https://www.devze.com 2023-03-28 20:26 出处:网络
I need to use the OpenFileDialog to select a fil开发者_StackOverflow社区e, but I can\'t use any of the MVVM-centric toolkits like Galgasoft that allow me to do this without violating the MVVM pattern.

I need to use the OpenFileDialog to select a fil开发者_StackOverflow社区e, but I can't use any of the MVVM-centric toolkits like Galgasoft that allow me to do this without violating the MVVM pattern.

How else can I achieve this?


Sure, here's an example of some code I use to read Excel files. It goes in a ViewModel and gets called from a SelectFileCommand

private void SelectFile()
{
    var dlg = new OpenFileDialog();
    dlg.DefaultExt = ".xls|.xlsx";
    dlg.Filter = "Excel documents (*.xls, *.xlsx)|*.xls;*.xlsx";

    if (dlg.ShowDialog() == true)
    {
        var file = new FileInfo(dlg.FileName);
        ReadExcelFile(file.FullName);
    }
}

private void ReadExcelFile(fileName)
{
    try
    {
        using (var conn = new OleDbConnection(string.Format(@"Provider=Microsoft.Ace.OLEDB.12.0;Data Source={0};Extended Properties=Excel 8.0", fileName)))
        {
            OleDbDataAdapter da = new OleDbDataAdapter("SELECT DISTINCT [File Number] FROM [Sheet1$]", conn);
            var dt = new DataTable();
            da.Fill(dt);

            int i;
            FileContents = (from row in dt.AsEnumerable()
                            where int.TryParse(row[0].ToString(), out i)
                            select row[0]).ToList()
                            .ConvertAll<int>(p => int.Parse(p.ToString()));
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("Unable to read contents:\n\n" + ex.Message, "Error");
    }
}

You need to reference Microsoft.Win32 for the OpenFileDialog


You can create a custom control, so you can just bind a string from it to your viewmodel property.

The custom control I usually create is composed from:

  • Textbox or textblock
  • Button with an image as template
  • String dependency property where the file path will be wrapped to

So the *.xaml file would be like this

<Grid>

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.Column="0" Text="{Binding Text, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
    <Button Grid.Column="1"
            Click="Button_Click">
        <Button.Template>
            <ControlTemplate>
                <Image Grid.Column="1" Source="../Images/carpeta.png"/>
            </ControlTemplate>                
        </Button.Template>
    </Button>

</Grid>

And the *.cs file:

    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text",
        typeof(string),
        typeof(customFilePicker),
        new FrameworkPropertyMetadata(
            null,
            FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal));

    public string Text
    {
        get
        {
            return this.GetValue(TextProperty) as String;
        }
        set
        {
            this.SetValue(TextProperty, value);
        }
    }

    public FilePicker()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();

        if(openFileDialog.ShowDialog() == true)
        {
            this.Text = openFileDialog.FileName;
        }
    }

At the end you can bind it to your view model:

<controls:customFilePicker Text="{Binding Text}"}/>
0

精彩评论

暂无评论...
验证码 换一张
取 消